5.4.1. Firmware Interface

5.4.1.1. Overview

Position and velocity estimators in MCAF have several common characteristics. This section describes their methods, types, and semantics. A fictional estimator called Xyz will be used for example purposes.

5.4.1.2. Terminology

The following terms are used in MCAF to describe estimators:

Term       

Description

active

An active estimator is in operation and determining an angle and velocity. (All estimators that are selected in the Customize page of motorBench® Development Suite are active by default.)

primary

The primary estimator determines the angle and velocity used for commutation and feedback. Several estimators can be active simultaneously, but only one can be the primary estimator at any given instant.

intrusive

An intrusive estimator is one that perturbs controller outputs with some sort of excitation waveform, which may have a minor impact on the motor currents and voltages. A non-intrusive estimator determines an angle and velocity through existing measurements of current, voltage, or other sensors, and does not affect operation except through its use as a primary estimator. Most estimators are non-intrusive.

5.4.1.3. Filesystem location

Call sites utilizing the estimators can be found in commutation.c and commutation.h; storage is declared in commutation_types.h.

Implementation of individual estimator modules are found in the commutation directory. They will typically consist of at least one .h file and one .c file, for example commutation/xyz.h and commutation/xyz.c. Some estimator modules set apart type definitions in a types.h file, for example commutation/xyz_types.h. The estimator’s state variable structure is defined in the types.h file, if it is present, along with inline static getter methods; otherwise they are defined in the main .h file. Function prototypes are declared in the main .h file.

Estimator-specific parameters, such as delays, limits, and tuning gains, are generated in parameters/xyz_params.h.

5.4.1.4. Storage and types

Each estimator will have a state variable structure defined in commutation/xyz.h or commutation/xyz_types.h, for example:

// State variable structure for use by Xyz estimator
typedef struct tagMCAF_ESTIMATOR_XYZ {
   ...
} MCAF_ESTIMATOR_XYZ_T;

Storage for this state variable structure will be declared in commutation_types.h, which typically looks like this:

/**
 * Relative angle used for comparing estimator electrical angles
 */
typedef struct tagMCAF_RELATIVE_ANGLE_T
{
   MCAF_U_ANGLE_ELEC qei; /** quadrature encoder with velocity tracking loop */
} MCAF_RELATIVE_ANGLE_T;

/**
* State estimator data for position/velocity
*/
typedef struct tagMCAF_ESTIMATOR_T
{
   MCAF_ESTIMATOR_QEI_T qei;  /** quadrature encoder with velocity tracking loop */
   MCAF_ESTIMATOR_XYZ_T xyz;  /** XYZ estimator */
   MCAF_ESTIMATOR_INPUTS_T inputs;             /** inputs common to most estimators */
   MCAF_U_ANGLE_ELEC     theta;                   /** estimated rotor angle (electrical) */
   MCAF_U_VELOCITY_ELEC  omega;                   /** estimated rotor velocity (electrical) */
   MCAF_RELATIVE_ANGLE_T thetaRelativeTo;
} MCAF_ESTIMATOR_T;

inline static bool MCAF_EstimatorQeiIsActive(const MCAF_ESTIMATOR_T* pestimator) { return false; }
inline static bool MCAF_EstimatorXyzIsActive(const MCAF_ESTIMATOR_T* pestimator) { return true; }

where MCAF_ESTIMATOR_T is referenced in system_init.h as part of the main motor data structure, so that the Xyz estimator state variable is located in motor.estimator.xyz.

More than one estimator may be actively operating in code generated from MCAF, but exactly one estimator is the primary estimator used for commutation feedback.

The values in motor.estimator.thetaRelativeTo are the commutation angle of estimators, relative to the primary estimator. These values may be used for debugging or performance analysis, and include all estimators that are selected as reference estimators.

The MCAF_EstimatorXyzIsActive() function is a constant value that returns true or false for each estimator to indicate if it is the primary estimator.

Note: The use of “active” in the estimator firmware interface is incorrect at present. See the Errata for more information.

5.4.1.5. Entry points and methods

There are several entry points and methods associated with position and velocity estimators.

The entry points are as follows:

  • Initialization: MCAF_EstimatorXyzInit() is called during overall initialization. This happens once, shortly after power-on reset, and gives the estimator a chance to initialize its own state variables. Some estimators may depend on others, in which case the function MCAF_EstimatorXyzSetupOutputDependencies() is also called, to provide access from other estimator outputs.

  • Reinitialization at motor start: MCAF_EstimatorXyzStartupInit() is called whenever the main motor state machine transitions into the STARTUP state. This gives the estimator a chance to reinitialize its state variables at the beginning of motor startup.

  • Step function: MCAF_EstimatorXyzStep() is called at the main control rate, from MCAF_CommutationStep() in commutation.c.

    Some estimators may also have other entry points, called at the same rate as the step function:

    • MCAF_EstimatorXyzInteractionStep() — this contains any actions that are tightly coupled with other MCAF modules, and has access to the full motor data structure. (This is discouraged because it violates modularity, but is unavoidable in certain cases.)

    • MCAF_EstimatorXyzStartupDelayRequested() — this is a getter function that allows estimators to delay startup progress at certain points, so that the estimator can complete tasks of its own.

  • Selection of active commutation angle and velocity: In commutation.c, MCAF_CommutationStep() determines the angle and velocity from among the available estimators, typically via the following construct:

    if (MCAF_EstimatorXyzActive(pestimator))
    {
       pestimator->theta = MCAF_EstimatorXyzCommutationAngle(&pestimator->xyz);
       pestimator->omega = MCAF_EstimatorXyzElectricalFrequency(&pestimator->xyz);
    }
    

    The compiler will optimize out blocks of this sort for inactive estimators, where MCAF_EstimatorXyzActive() is known at compile time to be false.

The following are methods associated with each estimator.

// State variable structure for use by Xyz estimator
typedef struct tagMCAF_ESTIMATOR_XYZ {
   ...
} MCAF_ESTIMATOR_XYZ_T;

/**
 * Initializes Xyz state variables on reset.
 * @param xyz Xyz state variable structure
 */
void MCAF_EstimatorXyzInit(MCAF_ESTIMATOR_XYZ_T *xyz);

/**
 * Initializes Xyz state variables prior to starting motor.
 *
 * @param xyz Xyz state variable structure
 */
void MCAF_EstimatorXyzStartupInit(MCAF_ESTIMATOR_XYZ_T *xyz);

/**
 * Executes one control step of the Xyz estimator.
 *
 * @param xyz Xyz state variable structure
 * @param pinput Common input signals (e.g. stationary-frame voltage and current)
 * @param pmotor Motor parameters (e.g. resistance, inductance, etc.)
 */
void MCAF_EstimatorXyzStep(MCAF_ESTIMATOR_XYZ_T *xyz,
               const MCAF_STANDARD_INPUT_SIGNALS_T *pinput,
               const MCAF_MOTOR_PARAMETERS_T *pmotor,
               ...);

/**
 * Returns commutation angle
 *
 * @param xyz state
 * @return commutation angle
 */
inline static MCAF_U_ANGLE_ELEC MCAF_EstimatorXyzCommutationAngle(
               const MCAF_ESTIMATOR_XYZ_T *xyz)
               { return ... }

/**
 * Returns electrical frequency
 *
 * @param xyz state
 * @return electrical frequency
 */
inline static MCAF_U_VELOCITY_ELEC MCAF_EstimatorXyzElectricalFrequency(
               const MCAF_ESTIMATOR_XYZ_T *xyz)
               { return ... }

/**
 * Determine whether startup delay is requested
 *
 * @param xyz state
 * @param startupStatus startup status
 * @return whether a startup delay is requested
 */
inline static bool MCAF_EstimatorXyzStartupDelayRequested(
               const MCAF_ESTIMATOR_XYZ_T *xyz, MCAF_STARTUP_STATUS_T startupStatus)
               { return ... }

5.4.1.6. Method summary

These methods are summarized in the following table. (To save space, the prefix MCAF_EstimatorXyz is elided, so for example Init() refers to MCAF_EstimatorXyzInit())

Method

Summary

Call site

Applicability

Init()

One-time initialization

MCAF_CommutationInit()

all

SetupOutputDependencies()

One-time initialization for output dependencies

MCAF_CommutationInit()

Hybrid estimators

StartupInit()

Reinitialization at each startup

MCAF_CommutationStartupInit()

all

Step()

Step update function

MCAF_CommutationStep()

all

InteractionStep()

Secondary update function; needed only when tightly coupled to other modules

MCAF_CommutationStep()

as needed

CommutationAngle()

Getter, returns commutation angle

MCAF_CommutationStep()

all

ElectricalFrequency()

Getter, returns electrical frequency

MCAF_CommutationStep()

all

StartupDelayRequested()

Getter, returns whether a delay is requested.

Estimator may delay startup progress at certain points, by returning true.

MCAF_CommutationStep()

all

Active()

Getter, returns true if estimator angle is the primary estimator selected for commutation

MCAF_CommutationStep()

all

5.4.1.7. Errata

  • Use of “active” instead of “primary” (DB_MC-4325; Applicability: MCAF R4, R5, R6, R7) — the word “active” is used incorrectly in commutation.c and commutation_types.h and this will be fixed to “primary” in a future release, including changing MCAF_EstimatorXyzIsActive() to MCAF_EstimatorXyzIsPrimary().