Motion Magic for Spark MAX

Has anyone ever written a custom code to achieve the same thing as motion magic for sparkMAXes. If not, how can i ?

If I recall corectly, There isnt a built in function for the SparkMAX. You can use ProfieldPIDController on the rio.

And the documentations are right here

1 Like

Yes, we have.
(With some inspiration from PurpleLib)

These 2 classes include support for motion profiles for both position and velocity, feedforward, and pid.

This class uses the motor controller for the PID calculations, and handles FF and profiles on the RIO.

This class does everything outside the motor controller and sends only voltage requests.

The reason for the distinction between spark max and spark flex is that we have found that the internal encoder of our vortexes are more reliable than the ones on our motors which use the spark max controller

2 Likes

From what I’ve heard, something similar to MotionMagic called MAXMotion will be added.

3 Likes

So I have been trying to work with MaxMotion from the Rev 2025 beta.

I have had pretty good success when keeping the encoder units to default settings (ie distance: revolutions, and velocity: rpm).

code used that works as expected:

      leftConfig
                    .idleMode(IdleMode.kBrake)
                    .smartCurrentLimit(40)
                    .inverted(false);
      leftConfig.encoder
                    .positionConversionFactor(1.0) //revolutions
                    .velocityConversionFactor(1.0); //rpm
      //              .inverted(false);
      leftConfig.closedLoop
                    .feedbackSensor(FeedbackSensor.kPrimaryEncoder)
                    .p(0.5)
                    .i(0)
                    .d(0.0)
                    .velocityFF(0.0)
                    .maxOutput(1.0)
                    .minOutput(-1.0)
                    .maxMotion
                      .maxAcceleration(1000.0)
                      .maxVelocity(2000.0)
                      .allowedClosedLoopError(.1) 
                      ;

 leftDrive.configure(leftConfig, ResetMode.kResetSafeParameters, PersistMode.kPersistParameters);


public void maxMotionPosition(){
    leftController.setReference(leftSetpoint, ControlType.kMAXMotionPositionControl);

  }


I get a nice curve accelerate decelerate in a way that seems correct.

If I try to change the units to make since for my application (distance: meters, velocity: meters/s) then it does not seem to work for me.

configuration for code use that doesn’t get expected results:
(This is on a drivetrain: wheels barely inch along on blocks. I’ve played with the P value if it is increased much it starts making the motor bounce, but does not increase the speed)


    private final double DRIVE_GEAR_RATIO = (50.0/14.0)*(48.0/16.0);
    private final double WHEEL_CIRCUMFERENCE_METER = Math.PI*6.0*25.4/1000.0;




      leftConfig
                    .idleMode(IdleMode.kBrake)
                    .smartCurrentLimit(40)
                    .inverted(false);
      leftConfig.encoder
                    .positionConversionFactor(1.0/DRIVE_GEAR_RATIO*WHEEL_CIRCUMFERENCE_METER) //meters
                    .velocityConversionFactor(1.0/DRIVE_GEAR_RATIO*WHEEL_CIRCUMFERENCE_METER/60.0); //meters/sec
      //              .inverted(false);
      leftConfig.closedLoop
                    .feedbackSensor(FeedbackSensor.kPrimaryEncoder)
                    .p(50.0)//0.5)
                    .i(0)
                    .d(0.0)
                    .velocityFF(0.0)
                    .maxOutput(1.0)
                    .minOutput(-1.0)
                    .maxMotion
                      .maxAcceleration(1.49/2.0) should match 1000 rpm/s
                      .maxVelocity(1.49) //should match 2000 rpm
                      .allowedClosedLoopError(.1) //degrees
                      ;

Manually driving when I print the velocity to the dashboard it appears correct with the free speed at around 4.3 m/s

Has anyone had success when using a position and velocity conversion factor? If so what I am doing wrong.

Full code if interested. I am just toying with the left side of the drive base in the DriveSubsystem

2 Likes