SparkMax CAN C++ SetPosition with built in encoder


#1

Hello folks.
I have been able to get the CAN connected SparkMax with a brushless motor working. I have also figured out how to read the built in encoder postion.

what I have not been able to figure out is how to after setting the desired position , while leaving the P, I, D values etc to their assumed 0 default, how to actually get the motor to chase to that position.

The code currently can move the motor off its initial zero powerup starting postion via manual joystick button presses, and then I have a command that sets the “setReference” point to 0, with kPostion as the control type. But assuming I am setting the desired postion, I can’t seem to find a method that would tell the PID loop to engage and chase to that position.

Any ideas?

I will post some code samples of what I have so far if anyone is interested.

Thank you.

md,


#2

Here is some code segments that I have tried.

The set position command…

// Called just before this Command runs the first time
void SetSparkMotorPos::Initialize() {
Robot::wheelSubsystem->PositionSparkMotor(m_pos);
std::cout << “Setting Motor Pos Command” << std::endl;
}

// Called repeatedly when this Command is scheduled to run
void SetSparkMotorPos::Execute() {
Robot::wheelSubsystem->PositionSparkMotor(m_pos);
std::cout << “Setting Motor Pos: Exec” << std::endl;
}

// Make this return true when this Command no longer needs to run execute()
bool SetSparkMotorPos::IsFinished() {
return false;
}

// Called once after isFinished returns true
void SetSparkMotorPos::End() {
std::cout << “Setting Motor Pos END:” << std::endl;
}

// Called when another command which requires one or more of the same
// subsystems is scheduled to run
void SetSparkMotorPos::Interrupted() {
End();
}

////// and the set postion method that this command refers to…

void WheelSubsystem::PositionSparkMotor(double pos) {
std::cout << "GetP: " << speedMax11PID->GetP() << std::endl;
speedMax11PID->SetP(1.0);
std::cout << "GetP after set: " << speedMax11PID->GetP() << std::endl;
std::cout << “Position being set:” << pos << std::endl;
speedMax11PID->SetReference(pos,rev::ControlType::kPosition,0);

}

And while I know the constructors work for the sparkMax and its encoder, as I am getting outputs of the get encoder in print statements, I will include their definition below.
WheelSubsystem::WheelSubsystem() : frc::Subsystem(“WheelSubsystem”) {
speedMax11.reset(new rev::CANSparkMax(11,rev::CANSparkMaxLowLevel::MotorType::kBrushless));
speedMax11encoder.reset(new rev::CANEncoder(*speedMax11));
speedMax11PID.reset(new rev::CANPIDController(*speedMax11));

}

So folks , what am I missing? While I could use the PIDsubsystem class and do this in the rio, I am hoping to use the built in PID in the hardware to accompliish position control, and ultimately velocity control.

md


#3

Can you also set the min max output, each of the slots defaults to 0 or ‘disabled’.

speedMax11PID->SetOutputRange(-1,1);


#4

thanks, are you saying that while I may be setting the position, that without setting the output range, that I am never really sending a motor speed to the motor, and therefore unable to have the motor move?

let me know my logic is correct.
which is:

  1. set the cntl mode to position control, whith the desired postion, which should be a encoder value. The PID values will determine how fast/etc that the motor would work to close the delta between what the current encoder postion and the desired set point.

  2. If I ask to go to pos 100, and the encoder has just turned on, (pos 0) the difference between the two (100-0) will be sent to the motor as a “Set” speed value, which in this case is very much over 1. So that motor should take off “like a rocket” (perfect for this year’s game).

  3. By setting the range, would this limit the value between -1 and 1, and if I did not set the range, it would be 0 so, no matter what the pid function returned, it would send error*0 to motor and therefore not move?

md


#5

Wow, that worked btw, but you knew that. Setting the range now allows the motor to seek to its position.

But again, let me know if my logic above was correct.

Many thanks.

md