Save ~2800 bytes of RAM by not caching angle->trigger mapping (#3506)

Memory seems more valuable than CPU; use the O(lg n) lookup by angle.  A side effect is that it
seems to fix trigger lookup for the second phase of TRIGGERTYPE 53 544 TT_TRI _TACH 0.00
This commit is contained in:
Scott Smith 2021-11-09 04:03:27 -08:00 committed by GitHub
parent 7f373a6415
commit 158f719d95
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 304 additions and 316 deletions

View File

@ -288,7 +288,9 @@ void rpmShaftPositionCallback(trigger_event_e ckpSignalType,
#endif /* EFI_SENSOR_CHART */
// Always update instant RPM even when not spinning up
engine->triggerCentral.triggerState.updateInstantRpm(&engine->triggerCentral.triggerFormDetails, index, nowNt PASS_ENGINE_PARAMETER_SUFFIX);
engine->triggerCentral.triggerState.updateInstantRpm(
engine->triggerCentral.triggerShape, &engine->triggerCentral.triggerFormDetails,
index, nowNt PASS_ENGINE_PARAMETER_SUFFIX);
if (rpmState->isSpinningUp()) {
float instantRpm = engine->triggerCentral.triggerState.getInstantRpm();

View File

@ -61,17 +61,12 @@ TriggerWaveform::TriggerWaveform() :
wave.channels = h.channels;
}
TriggerFormDetails::TriggerFormDetails() {
memset(triggerIndexByAngle, 0, sizeof(triggerIndexByAngle));
}
void TriggerWaveform::initialize(operation_mode_e operationMode) {
isSynchronizationNeeded = true; // that's default value
bothFrontsRequired = false;
needSecondTriggerInput = false;
shapeWithoutTdc = false;
memset(expectedDutyCycle, 0, sizeof(expectedDutyCycle));
// memset(triggerIndexByAngle, 0, sizeof(triggerIndexByAngle));
setTriggerSynchronizationGap(2);
for (int gapIndex = 1; gapIndex < GAP_TRACKING_LENGTH ; gapIndex++) {
@ -355,13 +350,11 @@ void TriggerWaveform::setTriggerSynchronizationGap3(int gapIndex, float syncRati
}
/**
* this method is only used on initialization
*/
uint16_t TriggerWaveform::findAngleIndex(TriggerFormDetails *details, angle_t targetAngle) const {
size_t engineCycleEventCount = getLength();
efiAssert(CUSTOM_ERR_ASSERT, engineCycleEventCount != 0 && engineCycleEventCount <= 0xFFFF, "engineCycleEventCount", 0);
efiAssert(CUSTOM_ERR_ASSERT, engineCycleEventCount != 0 && engineCycleEventCount <= 0xFFFF,
"engineCycleEventCount", 0);
uint32_t left = 0;
uint32_t right = engineCycleEventCount - 1;
@ -370,20 +363,20 @@ uint16_t TriggerWaveform::findAngleIndex(TriggerFormDetails *details, angle_t ta
* Let's find the last trigger angle which is less or equal to the desired angle
* todo: extract binary search as template method?
*/
while (left <= right) {
int middle = (left + right) / 2;
angle_t eventAngle = details->eventAngles[middle];
do {
uint32_t middle = (left + right) / 2;
if (eventAngle < targetAngle) {
left = middle + 1;
} else if (eventAngle > targetAngle) {
right = middle - 1;
} else {
// Values are equal
return middle; // Key found
}
}
return left - 1;
if (details->eventAngles[middle] <= targetAngle) {
left = middle + 1;
} else {
right = middle - 1;
}
} while (left <= right);
left -= 1;
if (useOnlyRisingEdgeForTriggerTemp) {
left &= ~1U;
}
return left;
}
void TriggerWaveform::setShapeDefinitionError(bool value) {
@ -408,7 +401,7 @@ void findTriggerPosition(TriggerWaveform *triggerShape,
efiAssertVoid(CUSTOM_ERR_6577, !cisnan(angle), "findAngle#2");
fixAngle2(angle, "addFuel#2", CUSTOM_ERR_6555, getEngineCycle(triggerShape->getOperationMode()));
int triggerEventIndex = details->triggerIndexByAngle[(int)angle];
int triggerEventIndex = triggerShape->findAngleIndex(details, angle);
angle_t triggerEventAngle = details->eventAngles[triggerEventIndex];
angle_t offsetFromTriggerEvent = angle - triggerEventAngle;
@ -435,18 +428,6 @@ void TriggerWaveform::prepareShape(TriggerFormDetails *details DECLARE_ENGINE_PA
}
prepareEventAngles(this, details PASS_ENGINE_PARAMETER_SUFFIX);
int engineCycleInt = (int) getEngineCycle(operationMode);
for (int angle = 0; angle < engineCycleInt; angle++) {
uint16_t triggerShapeIndex = findAngleIndex(details, angle);
if (useOnlyRisingEdgeForTriggerTemp) {
// we need even index for front_only mode - so if odd indexes are rounded down by clearing the low bit
triggerShapeIndex &= 0xFFFE;
}
details->triggerIndexByAngle[angle] = triggerShapeIndex;
}
#endif
}

View File

@ -308,17 +308,11 @@ private:
*/
class TriggerFormDetails {
public:
TriggerFormDetails();
/**
* These angles are in event coordinates - with synchronization point located at angle zero.
* These values are pre-calculated for performance reasons.
*/
angle_t eventAngles[PWM_PHASE_MAX_COUNT];
/**
* this cache allows us to find a close-enough (with one degree precision) trigger wheel index by
* given angle with fast constant speed. That's a performance optimization for event scheduling.
*/
uint16_t triggerIndexByAngle[MAX(TWO_STROKE_CYCLE_DURATION, FOUR_STROKE_CYCLE_DURATION)];
};
void findTriggerPosition(

View File

@ -242,7 +242,10 @@ void TriggerStateWithRunningStatistics::movePreSynchTimestamps(DECLARE_ENGINE_PA
memcpy(timeOfLastEvent + firstDst, spinningEvents + firstSrc, eventsToCopy * sizeof(timeOfLastEvent[0]));
}
float TriggerStateWithRunningStatistics::calculateInstantRpm(TriggerFormDetails *triggerFormDetails, uint32_t current_index, efitick_t nowNt DECLARE_ENGINE_PARAMETER_SUFFIX) {
float TriggerStateWithRunningStatistics::calculateInstantRpm(
TriggerWaveform const & triggerShape, TriggerFormDetails *triggerFormDetails,
uint32_t current_index, efitick_t nowNt DECLARE_ENGINE_PARAMETER_SUFFIX) {
assertIsInBoundsWithResult((int)current_index, timeOfLastEvent, "calc timeOfLastEvent", 0);
// Record the time of this event so we can calculate RPM from it later
@ -257,7 +260,7 @@ float TriggerStateWithRunningStatistics::calculateInstantRpm(TriggerFormDetails
// Hunt for a tooth ~90 degrees ago to compare to the current time
angle_t previousAngle = currentAngle - 90;
fixAngle(previousAngle, "prevAngle", CUSTOM_ERR_TRIGGER_ANGLE_RANGE);
int prevIndex = triggerFormDetails->triggerIndexByAngle[(int)previousAngle];
int prevIndex = triggerShape.findAngleIndex(triggerFormDetails, previousAngle);
// now let's get precise angle for that event
angle_t prevIndexAngle = triggerFormDetails->eventAngles[prevIndex];
@ -307,8 +310,12 @@ void TriggerStateWithRunningStatistics::setLastEventTimeForInstantRpm(efitick_t
spinningEvents[spinningEventIndex++] = nowNt;
}
void TriggerStateWithRunningStatistics::updateInstantRpm(TriggerFormDetails *triggerFormDetails, uint32_t index, efitick_t nowNt DECLARE_ENGINE_PARAMETER_SUFFIX) {
m_instantRpm = calculateInstantRpm(triggerFormDetails, index, nowNt PASS_ENGINE_PARAMETER_SUFFIX);
void TriggerStateWithRunningStatistics::updateInstantRpm(
TriggerWaveform const & triggerShape, TriggerFormDetails *triggerFormDetails,
uint32_t index, efitick_t nowNt DECLARE_ENGINE_PARAMETER_SUFFIX) {
m_instantRpm = calculateInstantRpm(triggerShape, triggerFormDetails, index,
nowNt PASS_ENGINE_PARAMETER_SUFFIX);
#if EFI_SENSOR_CHART

View File

@ -202,7 +202,9 @@ public:
void movePreSynchTimestamps(DECLARE_ENGINE_PARAMETER_SIGNATURE);
#if EFI_ENGINE_CONTROL && EFI_SHAFT_POSITION_INPUT
void updateInstantRpm(TriggerFormDetails *triggerFormDetails, uint32_t index, efitick_t nowNt DECLARE_ENGINE_PARAMETER_SUFFIX);
void updateInstantRpm(
TriggerWaveform const & triggerShape, TriggerFormDetails *triggerFormDetails,
uint32_t index, efitick_t nowNt DECLARE_ENGINE_PARAMETER_SUFFIX);
#endif
/**
* Update timeOfLastEvent[] on every trigger event - even without synchronization
@ -211,7 +213,9 @@ public:
void setLastEventTimeForInstantRpm(efitick_t nowNt DECLARE_ENGINE_PARAMETER_SUFFIX);
private:
float calculateInstantRpm(TriggerFormDetails *triggerFormDetails, uint32_t index, efitick_t nowNt DECLARE_ENGINE_PARAMETER_SUFFIX);
float calculateInstantRpm(
TriggerWaveform const & triggerShape, TriggerFormDetails *triggerFormDetails,
uint32_t index, efitick_t nowNt DECLARE_ENGINE_PARAMETER_SUFFIX);
float m_instantRpm = 0;
float m_instantRpmRatio = 0;

View File

@ -323,8 +323,8 @@ TEST(misc, testRpmCalculator) {
ASSERT_EQ(0, GET_RPM());
// triggerIndexByAngle update is now fixed! prepareOutputSignals() wasn't reliably called
ASSERT_EQ(5, engine->triggerCentral.triggerFormDetails.triggerIndexByAngle[240]);
ASSERT_EQ(5, engine->triggerCentral.triggerFormDetails.triggerIndexByAngle[241]);
ASSERT_EQ(5, engine->triggerCentral.triggerShape.findAngleIndex(&engine->triggerCentral.triggerFormDetails, 240));
ASSERT_EQ(5, engine->triggerCentral.triggerShape.findAngleIndex(&engine->triggerCentral.triggerFormDetails, 241));
eth.fireTriggerEvents(/* count */ 48);
@ -389,8 +389,8 @@ TEST(misc, testRpmCalculator) {
assertEqualsM("3/3", start + 14777, engine->executor.getForUnitTest(2)->momentX);
engine->executor.clear();
ASSERT_EQ(5, engine->triggerCentral.triggerFormDetails.triggerIndexByAngle[240]);
ASSERT_EQ(5, engine->triggerCentral.triggerFormDetails.triggerIndexByAngle[241]);
ASSERT_EQ(5, engine->triggerCentral.triggerShape.findAngleIndex(&engine->triggerCentral.triggerFormDetails, 240));
ASSERT_EQ(5, engine->triggerCentral.triggerShape.findAngleIndex(&engine->triggerCentral.triggerFormDetails, 241));
eth.fireFall(5);

View File

@ -3001,270 +3001,270 @@ event 276 1 1 362.67
event 277 1 0 364.00
event 278 1 1 365.33
event 279 1 0 366.67
event 280 1 1 0.00
event 281 1 0 0.00
event 282 1 1 0.00
event 283 1 0 0.00
event 284 1 1 0.00
event 285 1 0 0.00
event 286 1 1 0.00
event 287 1 0 0.00
event 288 1 1 0.00
event 289 1 0 0.00
event 290 1 1 0.00
event 291 1 0 0.00
event 292 1 1 0.00
event 293 1 0 0.00
event 294 1 1 0.00
event 295 1 0 0.00
event 296 1 1 0.00
event 297 1 0 0.00
event 298 1 1 0.00
event 299 1 0 0.00
event 300 1 1 0.00
event 301 1 0 0.00
event 302 1 1 0.00
event 303 1 0 0.00
event 304 1 1 0.00
event 305 1 0 0.00
event 306 1 1 0.00
event 307 1 0 0.00
event 308 1 1 0.00
event 309 1 0 0.00
event 310 1 1 0.00
event 311 1 0 0.00
event 312 1 1 0.00
event 313 1 0 0.00
event 314 1 1 0.00
event 315 1 0 0.00
event 316 1 1 0.00
event 317 1 0 0.00
event 318 1 1 0.00
event 319 1 0 0.00
event 320 1 1 0.00
event 321 1 0 0.00
event 322 1 1 0.00
event 323 1 0 0.00
event 324 1 1 0.00
event 325 1 0 0.00
event 326 1 1 0.00
event 327 1 0 0.00
event 328 1 1 0.00
event 329 1 0 0.00
event 330 1 1 0.00
event 331 1 0 0.00
event 332 1 1 0.00
event 333 1 0 0.00
event 334 1 1 0.00
event 335 1 0 0.00
event 336 1 1 0.00
event 337 1 0 0.00
event 338 1 1 0.00
event 339 1 0 0.00
event 340 1 1 0.00
event 341 1 0 0.00
event 342 1 1 0.00
event 343 1 0 0.00
event 344 1 1 0.00
event 345 1 0 0.00
event 346 1 1 0.00
event 347 1 0 0.00
event 348 1 1 0.00
event 349 1 0 0.00
event 350 1 1 0.00
event 351 1 0 0.00
event 352 1 1 0.00
event 353 1 0 0.00
event 354 1 1 0.00
event 355 1 0 0.00
event 356 1 1 0.00
event 357 1 0 0.00
event 358 1 1 0.00
event 359 1 0 0.00
event 360 1 1 0.00
event 361 1 0 0.00
event 362 1 1 0.00
event 363 1 0 0.00
event 364 1 1 0.00
event 365 1 0 0.00
event 366 1 1 0.00
event 367 1 0 0.00
event 368 1 1 0.00
event 369 1 0 0.00
event 370 1 1 0.00
event 371 1 0 0.00
event 372 1 1 0.00
event 373 1 0 0.00
event 374 1 1 0.00
event 375 1 0 0.00
event 376 1 1 0.00
event 377 1 0 0.00
event 378 1 1 0.00
event 379 1 0 0.00
event 380 1 1 0.00
event 381 1 0 0.00
event 382 1 1 0.00
event 383 1 0 0.00
event 384 1 1 0.00
event 385 1 0 0.00
event 386 1 1 0.00
event 387 1 0 0.00
event 388 1 1 0.00
event 389 1 0 0.00
event 390 1 1 0.00
event 391 1 0 0.00
event 392 1 1 0.00
event 393 1 0 0.00
event 394 1 1 0.00
event 395 1 0 0.00
event 396 1 1 0.00
event 397 1 0 0.00
event 398 1 1 0.00
event 399 1 0 0.00
event 400 1 1 0.00
event 401 1 0 0.00
event 402 1 1 0.00
event 403 1 0 0.00
event 404 1 1 0.00
event 405 1 0 0.00
event 406 1 1 0.00
event 407 1 0 0.00
event 408 1 1 0.00
event 409 1 0 0.00
event 410 1 1 0.00
event 411 1 0 0.00
event 412 1 1 0.00
event 413 1 0 0.00
event 414 1 1 0.00
event 415 1 0 0.00
event 416 1 1 0.00
event 417 1 0 0.00
event 418 1 1 0.00
event 419 1 0 0.00
event 420 1 1 0.00
event 421 1 0 0.00
event 422 1 1 0.00
event 423 1 0 0.00
event 424 1 1 0.00
event 425 1 0 0.00
event 426 1 1 0.00
event 427 1 0 0.00
event 428 1 1 0.00
event 429 1 0 0.00
event 430 1 1 0.00
event 431 1 0 0.00
event 432 1 1 0.00
event 433 1 0 0.00
event 434 1 1 0.00
event 435 1 0 0.00
event 436 1 1 0.00
event 437 1 0 0.00
event 438 1 1 0.00
event 439 1 0 0.00
event 440 1 1 0.00
event 441 1 0 0.00
event 442 1 1 0.00
event 443 1 0 0.00
event 444 1 1 0.00
event 445 1 0 0.00
event 446 1 1 0.00
event 447 1 0 0.00
event 448 1 1 0.00
event 449 1 0 0.00
event 450 1 1 0.00
event 451 1 0 0.00
event 452 1 1 0.00
event 453 1 0 0.00
event 454 1 1 0.00
event 455 1 0 0.00
event 456 1 1 0.00
event 457 1 0 0.00
event 458 1 1 0.00
event 459 1 0 0.00
event 460 1 1 0.00
event 461 1 0 0.00
event 462 1 1 0.00
event 463 1 0 0.00
event 464 1 1 0.00
event 465 1 0 0.00
event 466 1 1 0.00
event 467 1 0 0.00
event 468 1 1 0.00
event 469 1 0 0.00
event 470 1 1 0.00
event 471 1 0 0.00
event 472 1 1 0.00
event 473 1 0 0.00
event 474 1 1 0.00
event 475 1 0 0.00
event 476 1 1 0.00
event 477 1 0 0.00
event 478 1 1 0.00
event 479 1 0 0.00
event 480 1 1 0.00
event 481 1 0 0.00
event 482 1 1 0.00
event 483 1 0 0.00
event 484 1 1 0.00
event 485 1 0 0.00
event 486 1 1 0.00
event 487 1 0 0.00
event 488 1 1 0.00
event 489 1 0 0.00
event 490 1 1 0.00
event 491 1 0 0.00
event 492 1 1 0.00
event 493 1 0 0.00
event 494 1 1 0.00
event 495 1 0 0.00
event 496 1 1 0.00
event 497 1 0 0.00
event 498 1 1 0.00
event 499 1 0 0.00
event 500 1 1 0.00
event 501 1 0 0.00
event 502 1 1 0.00
event 503 1 0 0.00
event 504 1 1 0.00
event 505 1 0 0.00
event 506 1 1 0.00
event 507 1 0 0.00
event 508 1 1 0.00
event 509 1 0 0.00
event 510 1 1 0.00
event 511 1 0 0.00
event 512 1 1 0.00
event 513 1 0 0.00
event 514 1 1 0.00
event 515 1 0 0.00
event 516 1 1 0.00
event 517 1 0 0.00
event 518 1 1 0.00
event 519 1 0 0.00
event 520 1 1 0.00
event 521 1 0 0.00
event 522 1 1 0.00
event 523 1 0 0.00
event 524 1 1 0.00
event 525 1 0 0.00
event 526 1 1 0.00
event 527 1 0 0.00
event 528 1 1 0.00
event 529 1 0 0.00
event 530 1 1 0.00
event 531 1 0 0.00
event 532 1 1 0.00
event 533 1 0 0.00
event 534 1 1 0.00
event 535 1 0 0.00
event 536 1 1 0.00
event 537 1 0 0.00
event 538 1 1 0.00
event 539 1 0 0.00
event 540 1 1 0.00
event 541 1 0 0.00
event 542 1 1 0.00
event 543 1 0 0.00
event 280 1 1 368.00
event 281 1 0 369.33
event 282 1 1 370.67
event 283 1 0 372.00
event 284 1 1 373.33
event 285 1 0 374.67
event 286 1 1 376.00
event 287 1 0 377.33
event 288 1 1 378.67
event 289 1 0 380.00
event 290 1 1 381.33
event 291 1 0 382.67
event 292 1 1 384.00
event 293 1 0 385.33
event 294 1 1 386.67
event 295 1 0 388.00
event 296 1 1 389.33
event 297 1 0 390.67
event 298 1 1 392.00
event 299 1 0 393.33
event 300 1 1 394.67
event 301 1 0 396.00
event 302 1 1 397.33
event 303 1 0 398.67
event 304 1 1 400.00
event 305 1 0 401.33
event 306 1 1 402.67
event 307 1 0 404.00
event 308 1 1 405.33
event 309 1 0 406.67
event 310 1 1 408.00
event 311 1 0 409.33
event 312 1 1 410.67
event 313 1 0 412.00
event 314 1 1 413.33
event 315 1 0 414.67
event 316 1 1 416.00
event 317 1 0 417.33
event 318 1 1 418.67
event 319 1 0 420.00
event 320 1 1 421.33
event 321 1 0 422.67
event 322 1 1 424.00
event 323 1 0 425.33
event 324 1 1 426.67
event 325 1 0 428.00
event 326 1 1 429.33
event 327 1 0 430.67
event 328 1 1 432.00
event 329 1 0 433.33
event 330 1 1 434.67
event 331 1 0 436.00
event 332 1 1 437.33
event 333 1 0 438.67
event 334 1 1 440.00
event 335 1 0 441.33
event 336 1 1 442.67
event 337 1 0 444.00
event 338 1 1 445.33
event 339 1 0 446.67
event 340 1 1 448.00
event 341 1 0 449.33
event 342 1 1 450.67
event 343 1 0 452.00
event 344 1 1 453.33
event 345 1 0 454.67
event 346 1 1 456.00
event 347 1 0 457.33
event 348 1 1 458.67
event 349 1 0 460.00
event 350 1 1 461.33
event 351 1 0 462.67
event 352 1 1 464.00
event 353 1 0 465.33
event 354 1 1 466.67
event 355 1 0 468.00
event 356 1 1 469.33
event 357 1 0 470.67
event 358 1 1 472.00
event 359 1 0 473.33
event 360 1 1 474.67
event 361 1 0 476.00
event 362 1 1 477.33
event 363 1 0 478.67
event 364 1 1 480.00
event 365 1 0 481.33
event 366 1 1 482.67
event 367 1 0 484.00
event 368 1 1 485.33
event 369 1 0 486.67
event 370 1 1 488.00
event 371 1 0 489.33
event 372 1 1 490.67
event 373 1 0 492.00
event 374 1 1 493.33
event 375 1 0 494.67
event 376 1 1 496.00
event 377 1 0 497.33
event 378 1 1 498.67
event 379 1 0 500.00
event 380 1 1 501.33
event 381 1 0 502.67
event 382 1 1 504.00
event 383 1 0 505.33
event 384 1 1 506.67
event 385 1 0 508.00
event 386 1 1 509.33
event 387 1 0 510.67
event 388 1 1 512.00
event 389 1 0 513.33
event 390 1 1 514.67
event 391 1 0 516.00
event 392 1 1 517.33
event 393 1 0 518.67
event 394 1 1 520.00
event 395 1 0 521.33
event 396 1 1 522.67
event 397 1 0 524.00
event 398 1 1 525.33
event 399 1 0 526.67
event 400 1 1 528.00
event 401 1 0 529.33
event 402 1 1 530.67
event 403 1 0 532.00
event 404 1 1 533.33
event 405 1 0 534.67
event 406 1 1 536.00
event 407 1 0 537.33
event 408 1 1 538.67
event 409 1 0 540.00
event 410 1 1 541.33
event 411 1 0 542.67
event 412 1 1 544.00
event 413 1 0 545.33
event 414 1 1 546.67
event 415 1 0 548.00
event 416 1 1 549.33
event 417 1 0 550.67
event 418 1 1 552.00
event 419 1 0 553.33
event 420 1 1 554.67
event 421 1 0 556.00
event 422 1 1 557.33
event 423 1 0 558.67
event 424 1 1 560.00
event 425 1 0 561.33
event 426 1 1 562.67
event 427 1 0 564.00
event 428 1 1 565.33
event 429 1 0 566.67
event 430 1 1 568.00
event 431 1 0 569.33
event 432 1 1 570.67
event 433 1 0 572.00
event 434 1 1 573.33
event 435 1 0 574.67
event 436 1 1 576.00
event 437 1 0 577.33
event 438 1 1 578.67
event 439 1 0 580.00
event 440 1 1 581.33
event 441 1 0 582.67
event 442 1 1 584.00
event 443 1 0 585.33
event 444 1 1 586.67
event 445 1 0 588.00
event 446 1 1 589.33
event 447 1 0 590.67
event 448 1 1 592.00
event 449 1 0 593.33
event 450 1 1 594.67
event 451 1 0 596.00
event 452 1 1 597.33
event 453 1 0 598.67
event 454 1 1 600.00
event 455 1 0 601.33
event 456 1 1 602.67
event 457 1 0 604.00
event 458 1 1 605.33
event 459 1 0 606.67
event 460 1 1 608.00
event 461 1 0 609.33
event 462 1 1 610.67
event 463 1 0 612.00
event 464 1 1 613.33
event 465 1 0 614.67
event 466 1 1 616.00
event 467 1 0 617.33
event 468 1 1 618.67
event 469 1 0 620.00
event 470 1 1 621.33
event 471 1 0 622.67
event 472 1 1 624.00
event 473 1 0 625.33
event 474 1 1 626.67
event 475 1 0 628.00
event 476 1 1 629.33
event 477 1 0 630.67
event 478 1 1 632.00
event 479 1 0 633.33
event 480 1 1 634.67
event 481 1 0 636.00
event 482 1 1 637.33
event 483 1 0 638.67
event 484 1 1 640.00
event 485 1 0 641.33
event 486 1 1 642.67
event 487 1 0 644.00
event 488 1 1 645.33
event 489 1 0 646.67
event 490 1 1 648.00
event 491 1 0 649.33
event 492 1 1 650.67
event 493 1 0 652.00
event 494 1 1 653.33
event 495 1 0 654.67
event 496 1 1 656.00
event 497 1 0 657.33
event 498 1 1 658.67
event 499 1 0 660.00
event 500 1 1 661.33
event 501 1 0 662.67
event 502 1 1 664.00
event 503 1 0 665.33
event 504 1 1 666.67
event 505 1 0 668.00
event 506 1 1 669.33
event 507 1 0 670.67
event 508 1 1 672.00
event 509 1 0 673.33
event 510 1 1 674.67
event 511 1 0 676.00
event 512 1 1 677.33
event 513 1 0 678.67
event 514 1 1 680.00
event 515 1 0 681.33
event 516 1 1 682.67
event 517 1 0 684.00
event 518 1 1 685.33
event 519 1 0 686.67
event 520 1 1 688.00
event 521 1 0 689.33
event 522 1 1 690.67
event 523 1 0 692.00
event 524 1 1 693.33
event 525 1 0 694.67
event 526 1 1 696.00
event 527 1 0 697.33
event 528 1 1 698.67
event 529 1 0 700.00
event 530 1 1 701.33
event 531 1 0 702.67
event 532 1 1 704.00
event 533 1 0 705.33
event 534 1 1 706.67
event 535 1 0 708.00
event 536 1 1 709.33
event 537 1 0 710.67
event 538 1 1 712.00
event 539 1 0 713.33
event 540 1 1 714.67
event 541 1 0 716.00
event 542 1 1 717.33
event 543 1 0 718.67
TRIGGERTYPE 54 110 TT_GM_60_2_2_2 0.00
# duty 0.98 0.45
event 0 0 1 0.00