The CalculateCorrection converter calculates the correction to apply to a cycle, and triggers a trim to be applied.

The converter internally keeps track of the reference to correct with respect to , and can be triggered up to 2 times per cycle; once for the first prediction from theCycle prediction converter, and for the second time if the cycle is detected as a Dynamic Economy or Full Economy.

Triggers

Parameters

  • trimStart At which CTime the trim is cut to start
  • trimEnd At which CTime the trim is cut to end
  • gain: Trim gain, ideally below 1.0
  • enabled: enable or disable trimming

Logic

Saving reference

First trigger

The converter internally keeps track of the of each (LSA) cycle in a dictionary. If a reference does not exist for a cycle at trigger time, the CycleData.field_pred is taken as first reference for the corresponding CycleData.cycle key. In addition, the CycleData.cycle_timestamp is saved to know which played cycle was taken as reference.

For the first cycle, the, a is not calculated, but only for subsequent cycles.

Second trigger

The converter is only triggered a second time if the cycle is detected as an economy cycle. If the cycle was taken as reference, the saved reference must be removed, and a new reference is set for the economy mode cycle so that when the normal cycle comes the next time, the reference is set correctly.

Info

Note that for saving references, separate references are saved for normal, DYNECO and FULLECO cycles

if (
	cycle_data.reference_timestamp is not None
	and np.allclose(cycle_data.cycle_timestamp, cycle_data.reference_timestamp)
	and cycle_data.cycle.endswith("ECO")
):
	cycle_name = "_".join(cycle_data.cycle.split("_")[:-1])
 
	# compare non-ECO cycle to ECO cycle, if the same, delete the reference
	# because the ECO cycle is the reference
	if self._field_ref_timestamps[cycle_name] == cycle_data.cycle_timestamp:
		msg = f"{cycle_data}: Last cycle was ECO, need to delete the last reference."
		log.debug(msg)
 
		self.resetReference(cycle_name)
	cycle_data.reference_timestamp = None
 
# set new reference

calculation

For subsequent cycles, the CycleData.field_ref and CycleData.reference_timestamp is set, and is calculated as

And set as the CycleData.delta_applied , which is the to apply with respect to the reference. However the trim that will be applied to LSA and the subsequent new must be calculated with respect to the that the was computed with, i.e. the that was in place at prediction time (and was constructed from), and not the at trim time. The is stored in the CycleData.correction field.

And the new will be stored in the CycleData.correction_applied field and emitted for Trim send

When modeling Eddy current decay, the eddy current field depends purely on the history, and not the excitation current at the point of evaluation . So the reference to correct w.r.t. needs to be updated so that

Reset reference

When ResetReference is triggered with a cycle name, the entry in the internal reference tracker will be removed for that cycle, and a new reference will be taken the next cycle comes.

Output

Trim send

The new is emitted with a comment and cycle name for an LSA trim actor to apply the trim (on UCAP), or emitted as a Qt signal for sps-app-hysteresis.

newCycleDataAvailable

The CycleData with the delta_applied and correction_applied fields, along with field_ref and reference_timestamp set (if not the cycle the reference was taken from).

referenceReset

A signal containing the cycle name of the cycle whose reference was reset. This signal is emitted both when a manual reset is done, or on Second trigger.