Skip to content

Motion Magic

CoolProGamer edited this page Oct 8, 2024 · 2 revisions

What is motion magic?

Motion Magic is a control mode that provides the awesomeness of Motion profiling,

(Motion profiling is a way to define and graphically depict how a component should achieve the specified travel, in terms of velocity and time),

without having to generate trajectories from one point to another. When using Motion Magic, the motor will move to a target position using a motion profile, while honoring the user specified acceleration, maximum velocity (cruise velocity), and optional jerk.

Motion Magic functions by generating a trapezoidal/S-Curve velocity profile that does not exceed the specified cruise velocity, acceleration, or jerk. This is done automatically by the motor controller.

The Benefits

The benefits of this control mode over “simple” PID position closed-looping are:

  • Control of the mechanism throughout the entire motion (as opposed to racing to the end target position)

  • Control of the mechanism’s inertia to ensure smooth transitions between setpoints

  • Improved repeatability despite changes in battery load

  • Improved repeatability despite changes in motor load

Uses in FRC code

The Motion Magic® jerk, acceleration, and cruise velocity can be configured in code using a MotionMagicConfigs(a object in java).

    var talonFXConfigs = new TalonFXConfiguration();
    
    // set slot 0 variables, k is hungarian notation
    var slot0Configs = talonFXConfigs.Slot0;
    slot0Configs.kS = 0.25; // Add 0.25 V output to overcome static friction
    slot0Configs.kV = 0.12; // A velocity target of 1 rps results in 0.12 V output
    slot0Configs.kA = 0.01; // An acceleration of 1 rps/s requires 0.01 V output
    slot0Configs.kP = 4.8; // A position error of 2.5 rotations results in 12 V output
    slot0Configs.kI = 0; // no output for integrated error
    slot0Configs.kD = 0.1; // A velocity error of 1 rps results in 0.1 V output
    
    // set Motion Magic settings
    var motionMagicConfigs = talonFXConfigs.MotionMagic;
    motionMagicConfigs.MotionMagicCruiseVelocity = 80; // Target cruise velocity of 80 rotations per seconds
    motionMagicConfigs.MotionMagicAcceleration = 160; // Target acceleration of 160 rps/s (0.5 seconds)
    motionMagicConfigs.MotionMagicJerk = 1600; // Target jerk of 1600 rps/s/s (0.1 seconds)
    
    m_talonFX.getConfigurator().apply(talonFXConfigs);

For more information on configs, visit the PID documentation.

Once the variables are configured, the Motion Magic® request can be sent to the TalonFX. The control request object has an optional feedforward term that can be used to add an arbitrary value to the output, which can be useful to account for the effects of gravity.

    final MotionMagicVoltage m_request = new MotionMagicVoltage(0);
    
    // set target position to 100 rotations
    m_talonFX.setControl(m_request.withPosition(100));

Motion Magic Plus (Dynamic Motion Magic)

This feature requires the device to be Pro licensed and on a CANivore. When unlicensed, the TalonFX will disable control output and trip the UnlicensedFeatureInUse fault.

Using a Pro-licensed Talon FX connected to a CANivore allows Dynamic Motion Magic to be used, allowing for the cruise velocity, acceleration, and jerk to be modified directly in the control request during motion. This can be used to set up different values for acceleration vs deceleration or to speed up and slow down the profile on the fly.

The movement variables are configured in the same way as a regular Motion Magic® request. However, the cruise velocity, acceleration, and jerk parameters are set up in the control request, not the Motion Magic config group.

Once the variables are configured, the Dynamic Motion Magic request can be sent to the TalonFX. The control request object has an optional feedforward term that can be used to add an arbitrary value to the output, which can be useful to account for the effects of gravity.

    // create a Dynamic Motion Magic request, voltage output
    // default velocity of 80 rps, acceleration of 400 rot/s^2, and jerk of 4000 rot/s^3
    final DynamicMotionMagicVoltage m_request =
       new DynamicMotionMagicVoltage(0, 80, 400, 4000);
    
    if (m_joy.getAButton()) {
       // while the joystick A button is held, use a slower profile
       m_request.Velocity = 40; // rps
       m_request.Acceleration = 80; // rot/s^2
       m_request.Jerk = 400; // rot/s^3
    } else {
       // otherwise use a faster profile
       m_request.Velocity = 80; // rps
       m_request.Acceleration = 400; // rot/s^2
       m_request.Jerk = 4000; // rot/s^3
    }
    
    // set target position to 100 rotations
    m_talonFX.setControl(m_request.withPosition(100));
    

Clone this wiki locally