We successfully use MotionMagic PID for linear driving and Software PID via WPILIB for turning in the regular WestCoast drive chassis.
We’re trying to figure out how to use Pigeon IMU with Falcons for hardware PID turning. In other words, the task is - use hardware PID on Falcon to turn, say, 45 degrees. Note that software PID turn is working, so that’s not the point. Right now we experiment with just one TalonFX. The chassis has two, so once we get things going with one, we will apply similar logic to the other one to make in-place turn.
We’re trying to configure PID using Pigeon on slot #1 of the TalonFX.
Here is the code we have:
The Pigeon is connected to TalonSRX, and is defined like this -
WPI_TalonSRX pigeonIMUController = new WPI_TalonSRX(4);
private WPI_TalonSRX pigeyTalonSRX;
private PigeonIMU bird = new PigeonIMU(pigeonIMUController);
There is a public getBird() method that exposes it to other subsystems.
The Talon in question is defined like this:
WPI_TalonFX rightmotor = new WPI_TalonFX(10);
The PID configuration for it is defined like this:
rightConfig.remoteFilter0.remoteSensorSource = RemoteSensorSource.Pigeon_Yaw;
rightConfig.remoteFilter0.remoteSensorDeviceID =
(RobotContainer.pigeonIMUSubsystem.getBird()).getDeviceID();
System.out.println((RobotContainer.pigeonIMUSubsystem.getBird()).getDeviceID());
rightConfig.primaryPID.selectedFeedbackSensor =
TalonFXFeedbackDevice.RemoteSensor0.toFeedbackDevice();
rightConfig.primaryPID.selectedFeedbackCoefficient = 3600/8192;
rightmotor.setStatusFramePeriod(StatusFrameEnhanced.Status_12_Feedback1, 20, 30);
rightmotor.setStatusFramePeriod(StatusFrameEnhanced.Status_13_Base_PIDF0, 20, 30);
rightmotor.setStatusFramePeriod(StatusFrameEnhanced.Status_14_Turn_PIDF1, 20, 30);
(RobotContainer.pigeonIMUSubsystem.getBird()).setStatusFramePeriod(PigeonIMU_StatusFrame.CondStatus_9_SixDeg_YPR , 5, 30);
rightConfig.neutralDeadband = 0.001;
leftConfig.peakOutputForward = +0.3;
leftConfig.peakOutputReverse = -0.3;
rightConfig.peakOutputForward = +0.3;
rightConfig.peakOutputReverse = -0.3;
rightConfig.slot1.kP = 0.75;
rightConfig.slot1.kI = 0;
rightConfig.slot1.kD = 0;
rightConfig.slot1.kF = 0.0;
rightConfig.slot1.integralZone = 200;
rightConfig.slot1.closedLoopPeakOutput = 0.3;
rightConfig.slot1.allowableClosedloopError = 0;
int closedLoopTimeMs = 1;
rightConfig.slot1.closedLoopPeriod = closedLoopTimeMs;
rightmotor.configAllSettings(rightConfig);
Finally, to actually activate the PID, I believe I need to do this:
rightmotor.selectProfileSlot(1, 0);
rightmotor.set(TalonFXControlMode.MotionMagic, 45);
and … nothing happened. The robot did not move. Note that Pigeon values are displayed correctly on SmartDashboard. We zero the Pigeon Yaw before activating the PID.
Now, I also saw the TalonFXControlMode.Position, and I was not sure if I need to use that one instead.
Note that similar logic works just fine for linear driving when a local encoder sensor is used instead of a remote Pigeon. If you have any suggestions, they would be much appreciated.
Thank you.