Our robot does not strafe well probably because of the amount of different weight distribution that is occurring in the frame. Is there any way I can implement code to use a gyro to constantly maintain the same heading for the robot to strafe very straight? Also, does the Gyro have to be in the middle of of the robot frame to work correctly? BTW right now we’re using the mecanum_polar method with a joystick that has the z axis for mecanum driving. Our team is all rookies right now because most of us are new to the team.
Are you familiar with the PIDController class?
Not really.
The gyroscope does not have to be at the COG of the robot, but it is helpful if it is somewhere near the COG.
How you do this depends greatly on your drive system. The two most likely drive chassis to use “strafing” are mecanum and h-drive. I do not have any experience with lobster, crab, or swerve.
Mecanum: The easiest way to do this is to use the Holonomic Drive class, in “field coordinates”. We got one of these working in December using the cRIO, and the code is posted at https://github.com/frc3946/MecanumDrivetrain.
H-drive: While strafing, use the “tank drive” wheels to maintain your bearing (that is, azimuth) while you strafe. This can be done using a PID, or probably just with a very simple “P” loop - if you’re too far left, rotate a bit to the right, if you’re too far left rotate a bit to the left. The amount of rotation would be proportional (that’s the P) to the error in your current bearing. If the proportionality constant is too large, you’ll oscillate around the correct angle; if too low, you’ll keep drifting away. We’re using H-drive this year, but haven’t written this yet - we have an adjustable strafe wheel mount, so we are hoping that we don’t rotate very much. In any case, our rotation will be controlled primarily by a pair of range finders rather than the gyro.
Take a look here Using a gyro to drive straight This tweaks the rotation input to your drive subroutine. It works with holonomic and skid steer drive methods, and implements a simple P-control. We have used it many times. While the PIDControl subsystem is a great tool to learn how to use ( and you should make it your friend ). It isn’t required in this case.
These yaw rate sensors work with the coriolis effect, and can be placed anywhere. Just keep it in the x-y plane of the chassis. Or in your case r, theta
Eric
A bit of amplification (with prodding from Ether):
The reason you want the gyro near the CoG is to reduce the accelerations due to roll, pitch, and yaw. This was definitely more important in previous years, when the gyroscope and accelerometer were most commonly located in adjacent square inches of board. It is probably more important these days to put your 'RIO near the CoG than the gyroscope. Of course, the easiest place to mount the gyroscope is on some of that nice flat space on top of the 'RIO, an inch or two from the Analog IO port. It is definitely important to mount the gyroscope board in a horizontal orientation, presuming that you’re using it for navigating along the carpet; it measures rotation rate around an axis going through the board.
Thanks for the heads up about strafing with unbalanced weight. This is our first year with mecanum. The team took our practice chassis (a wide bot) from last year and mounted 4 mecanum on it for the programmers to play with while the actual robot (a long-bot) was under construction. The practice chasis behaved very nicely, but last night we put ~80lbs over the front two wheels. Strafing was very problematic and the robot wanted to rotate.
We added some very simple code to the DriveWithJoystick code and it was able to work much better-- this is just me retyping it from memory, but it was something along the lines of:
public class DriveWithJoystick extends Command {
...
double m_lastAngle;
boolean m_trackAngle;
...
public void initialize() {
m_trackAngle=false;
}
public void execute() {
// get joystick readings x, y, rotation, and gyroAngle
...
if(rotation==0)
{
//User does not want rotation, If this just happened, note current angle
if (!m_trackAngle)
{
m_trackAngle=true;
m_lastAngle=gyroAngle;
}
//by here we are sure m_trackAngle is true and m_lastAngle
//is our target angle, either just set above or on some previous
//pass.
// programatically inject rotation if
// there is error. Use P part of PID only
double errVal=m_lastAngle-gyroAngle;
double P=0.02;
rotation= P * errVal; //proportional rotation injected to counter error
} else {
//User is applying rotation, stop tracking angle
m_trackAngle=false;
}
Robot.driveTrain.mecanumDrive(x,y,rotation,gyroAngle);
}
..
}
As we strafed with 80lbs over the front wheels, it would tend to rotate due to the weight imbalance. With P==0.02, around 10 degrees, we begin applying a 0.2 power to compensate. At 20 degrees we’re applying 0.4 power.
During normal balance the strafing maintained an angle of at most ~2 degrees from ideal, so the injected rotation will be around 0.04 which probably has some, but very little effect.
We did not yet try to tune the P, but it worked pretty good with the initial guess. I suspect a larger P would improve performance slightly-- it was a bit sluggish maintaining the angle. But it seems if we have a stack of 4 totes and a container out front (~40lbs) in addition to our ~30 lb fork, we will likely find ourselves in this situation and at least the practice chassis felt manageable with the cod modification. It all depends on how well the build team can pull the center of gravity toward the center of the robot.