Module: stepperMotor

Executive Summary

The stepper motor module simulates the actuation of a stepper motor. Given the initial motor angle \(\theta_0\), a fixed motor step angle \(\Delta\theta\), a fixed motor step time \(\Delta t\), and an input message containing an integer number of steps commanded, the motor states are computed at each time step and output from the module. The motor states include the scalar motor angle \(\theta\), scalar angle rate \(\dot{\theta}\), scalar angular acceleration \(\ddot{\theta}\), the current motor step count \(c_s\), and the number of steps commanded to the motor \(n_s\). The motor actuation through each step of the command sequence is profiled using a bang-bang acceleration profile. This module also includes logic for handling incoming reference commands that interrupt an unfinished motor actuation sequence. Because the stepper motor is unable to stop actuating during a step, it must finish actuating through the current step before it can begin following a new reference command.

Message Connection Description

The following table lists the module input and output messages.

Module I/O Messages

Msg Variable Name

Msg Type

Description

motorStepCommandInMsg

MotorStepCommandMsgPayload

Input message containing the number of commanded motor steps

stepperMotorOutMsg

StepperMotorMsgPayload

Output message containing the stepper motor states

Motor Step Actuation Profile

The motor states are profiled identically for each step in the command sequence. Specifically, a bang-bang acceleration profile is used to profile the motor states as a function of time. Given the motor step time \(\Delta t\) and motor step angle \(\Delta \theta\) as fixed parameters, the module calculates the required acceleration \(\ddot{\theta}_{\text{max}}\) that must be applied during each motor step.

\[| \ddot{\theta}_{\text{max}} | = \frac{4 \Delta \theta}{\Delta t^2}\]

Note that the motor can take either positive or negative steps. For a forward actuation command (\(n_s > 0\)), the calculated acceleration is applied positively for the first half of the step and negatively during the second half of the step. For a backward actuation command (\(n_s < 0\)), the acceleration is applied negatively during the first half of the step and positively during the second half of the step.

Given the initial time \(t_0\), the switch time \(t_s\) where the acceleration is alternated and the final time \(t_f\) when the step is complete is determined as

\[ \begin{align}\begin{aligned}t_s = t_0 + \frac{\Delta t}{2}\\t_f = t_0 + \Delta t\end{aligned}\end{align} \]

The other motor states can be kinematically profiled as a function of time by integrating the applied acceleration profile. The equations used to profile each motor step are

\[ \begin{align}\begin{aligned}\begin{split}\ddot{\theta}(t) = \begin{cases} \pm \ddot{\theta}_{\text{max}} & \text{if } t_0 \leq t < t_s \\ \mp \ddot{\theta}_{\text{max}} & \text{if } t_s \leq t \leq t_f \\ 0 & \text{if } t > t_f \end{cases}\end{split}\\\begin{split}\dot{\theta}(t) = \begin{cases} \pm \ddot{\theta}_{\text{max}} (t - t_0) & \text{if } t_0 \leq t < t_s \\ \mp \ddot{\theta}_{\text{max}} (t - t_f) & \text{if } t_s \leq t \leq t_f \\ 0 & \text{if } t > t_f \end{cases}\end{split}\\\begin{split}\theta(t) = \begin{cases} \frac{\pm \Delta \theta (t - t_0)^2}{2 (t_s - t_0)^2} + \theta_0 & \text{if } t_0 \leq t < t_s \\ \frac{\mp \Delta \theta (t - t_f)^2}{2 (t_s - t_f)^2} + \theta_{\text{ref}} & \text{if } t_s \leq t \leq t_f \\ \theta_{\text{ref}} & \text{if } t > t_f \end{cases}\end{split}\end{aligned}\end{align} \]

Note that the parameters \(t_0, t_s\) and \(t_f\) must be continually updated after each step is complete to reflect the advancement of time. Doing so enables use of the above equations for each motor step.

Important

If the motor actuation is interrupted by a new reference message while actuating through a step, the motor must finish actuating through the current step before it can begin following a new reference command. If the interrupting message is written when the motor is not in the midst of a step, the module resets the motor step count and immediately begins actuating to follow the new reference command.

Module Functions

Below is a list of functions that this simulation module performs

  • Reads the incoming motor step command message

  • Computes the motor states as a function of time

  • Writes the motor states to the module output message

  • Handles interruptions to motor actuation by resetting the motor actuation after the current step is complete

Module Assumptions and Limitations

  • The motor step angle and step time are fixed parameters (Cannot be negative)

  • The motor cannot stop actuating in the middle of a step

  • When the motor actuation is interrupted by a new reference command, the motor must complete its actuation through the current step before following the new command

  • The module update rate must be faster than or equal to the provided motor step time \(\Delta t\)

  • The module update rate cannot be slower than the motor step rate, or the motor actuation cannot be resolved

Test Description and Success Criteria

There are two tests for this module. The two tests are described in test_stepperMotor. The first test is a nominal test named test_stepper_motor_nominal. The second test named test_stepper_motor_interrupt tests the module logic for commands interrupting the motor actuation. Both tests configure two actuation commands. The nominal test separates the actuation commands by a rest period of 5 seconds. The interruption test interrupts the first command sequence after half of the commanded motor steps are completed. The time the second command message is written is determined using an interruption factor to specify what fraction of the next step is completed before the second command message is written. Both tests add 5 seconds to the end of each simulation for clarity when viewing the generated plots.

The success criteria for all tests is that the motor states converge to the computed reference values in the test at the end of each actuation sequence. Specifically, the motor angle, rate, acceleration, and step count are checked to converge to the reference values at the end of each simulation chunk. The motor rate and acceleration are checked to be zero at the end of each actuation sequence. Note that the motor acceleration is checked at one time step after the other motor states are checked because the motor acceleration is nonzero at the completion of each motor step. The motor acceleration is not zero until after the motor step is complete. This differs from the motor rate profile, which is zero at the completion of each motor step.

Nominal Test

The nominal unit test configures two actuation command segments with a rest period of 5 seconds between the commands. A rest period of 5 seconds is also added to the end of the simulation for clarity when viewing the generated plots. The initial motor angle, motor step angle, step time, and steps commanded for each actuation sequence are varied so that the motor actuates both forwards and backwards during the test. Zero steps commanded are also included in the test to check that the module correctly updates the motor states for a zero command message. The motor angle, rate, acceleration, and step count are checked to converge to the reference values at the end of each simulation chunk.

Interruption Test

The interruption unit test ensures that the module correctly handles reference messages that interrupt an unfinished motor actuation sequence. The initial motor angle, motor step angle, and step time are not varied in the interruption test because these parameters were already varied in the nominal test. The interruption test interrupts the first command sequence after half of the commanded motor steps are completed. The time the second command message is written is determined using an interruption factor to specify what fraction of the next step is completed before the second command message is written. Interruption factors of 0 and 1 are also included to ensure the module correctly resets the motor states when the interruption falls precisely when a step is completed. A rest period of 5 seconds is added to the end of the simulation for clarity when viewing the generated plots. The motor angle, rate, acceleration, and step count are checked to converge to the reference values at the end of each simulation chunk.


class StepperMotor : public SysModel
#include <stepperMotor.h>

Stepper motor class.

Public Functions

StepperMotor() = default

Constructor.

~StepperMotor() = default

Destructor.

void Reset(uint64_t currentSimNanos) override

Module reset method.

Parameters:

callTime – [ns] Time the method is called

void UpdateState(uint64_t currentSimNanos) override

Module update method. This method profiles the stepper motor actuation as a function of time. The motor states are then written to the output message.

Parameters:

callTime – [ns] Time the method is called

double getThetaInit() const

Getter method for the initial motor angle called thetaInit.

Returns:

double

double getStepAngle() const

Getter method for the motor step angle called stepAngle.

Returns:

double

double getStepTime() const

Getter method for the motor step time called stepTime.

Returns:

double

double getThetaDDotMax() const

Getter method for the maximum motor angular acceleration called thetaDDotMax.

Returns:

double

void setThetaInit(const double thetaInit)

Setter method for the initial motor angle.

Parameters:

thetaInit – [rad] Initial motor angle

void setStepAngle(const double stepAngle)

Setter method for the motor step angle.

Parameters:

stepAngle – [rad] Motor step angle

void setStepTime(const double stepTime)

Setter method for the motor step time.

Parameters:

stepTime – [s] Motor step time

Public Members

ReadFunctor<MotorStepCommandMsgPayload> motorStepCommandInMsg

Input msg for the number of commanded motor step counts.

Message<StepperMotorMsgPayload> stepperMotorOutMsg

Output msg for the stepper motor state information.

Private Functions

void actuateMotor(double t)

This method is used to simulate the stepper motor actuation in time.

Parameters:

t – [s] Time the method is called

void resetMotor()

This method resets the motor states when the current request is complete and a new request is received.

void updateStepParameters()

This method updates the step parameters after a step is completed.

bool isInStepFirstHalf(double t)

This method determines if the motor is in the first half of a step.

Parameters:

t – [s] Time the method is called

Returns:

bool

void computeStepFirstHalf(double t)

This method computes the motor states during the first half of each step.

Parameters:

t – [s] Time the method is called

bool isInStepSecondHalf(double t)

This method determines if the motor is in the second half of a step.

Parameters:

t – [s] Time the method is called

Returns:

bool

void computeStepSecondHalf(double t)

This method computes the motor states during the second half of each step.

Parameters:

t – [s] Time the method is called

void computeStepComplete(double t)

This method computes the motor states when a step is complete.

Parameters:

t – [s] Time the method is called

Private Members

double stepAngle = {}

[rad] Angle the stepper motor moves through for a single step (constant)

double stepTime = {}

[s] Time required for a single motor step (constant)

int stepsCommanded = {}

[steps] Number of commanded steps

int stepCount = {}

[steps] Current motor step count (number of steps taken)

double thetaInit = {}

[rad] Initial motor angle

double intermediateThetaInit = {}

[rad] Initial motor angle at the start of each step

double intermediateThetaRef = {}

[rad] Reference motor angle at the end of each step

double theta = {}

[rad] Current motor angle

double thetaDot = {}

[rad/s] Current motor angle rate

double thetaDDot = {}

[rad/s^2] Current motor angular acceleration

double thetaDDotMax = {}

[rad/s^2] Maximum angular acceleration of the stepper motor

double tInit = {}

[s] Simulation time at the beginning of each step

double previousWrittenTime = {-1}

[ns] Time the last input message was written

double ts = {}

[s] The simulation time halfway through each step (switch time for ang accel)

double tf = {}

[s] Simulation time when the current step will be completed

bool actuationComplete = {true}

Boolean designating the motor has fully completed the commanded actuation.

bool stepComplete = {true}

Boolean designating the completion of a step.

bool newMsg = {}

Boolean designating a new command message is written.

bool interruptMsg = {}

Boolean designating the new command message is interrupting motor actuation.

double a = {}

Parabolic constant for the first half of a step.

double b = {}

Parabolic constant for the second half of a step.