AndyMark Swerve and Steer (Has anybody gotten them to run properly)

Okay, so we bought AndyMark Swerve and Steer modules because they were all we could find at the time of purchasing we have managed to get the wheels to go forwards and backwards, but the rotation is currently super wacky.

First off, we cloned the repository from the following video and have been trying to modify it to fit our robot, but have so far not been successful. This is the first year we have used Java, and we don’t have anybody with a ton of programming experience with Java on our team either.

Secondly I’ll layout exactly how we got to where we’re at.

  1. We purchased andymark swerve and steel pre-assembled modules
  2. We swapped the CIM motors that came on them with NEO Brushless Motors.
  3. We kept the PG71 Gearmotors as the steering motors. (These came with built in “Two Channel Hall Effect” encoders.)
  4. We purchased MA3-Absolute Encoders from Andymark and connected them to the modules in the proper place and attached them with 40 tooth gears.
  5. We wired everything.

So at this point in time we have the NEO Brushless motors as drive motors and those are connected via SparkMax’s on the CAN Network.

The PG71 Gearmotors are setup also using SparkMax’s on the CAN Network.
We also added MA3 Absolute Encoders to the modules and wired those into the ANALOG ports on the RoboRIO.

We have a NavX2 plugged into the big port in the Middle of the RoboRIO and the lights come on.

Right now I think our biggest problem is that the code we have started with wasn’t written for the same swerve modules, and we don’t know all the parts of the code that need to be changed to work with our Swerve and Steer Modules.

Does anybody reading this have Java code that worked for Andymark Swerve and Steer modules?
Or if not Java then possibly LabView. We are struggling a lot with this, and are willing to go down some other routes if needed.

Otherwise with our code in it’s current state the next problem we have to conquer is getting our chassisspeeds variable inputed into the proper spot. (We can go deeper on explaining this if somebody reading this wants to help, but I’ve already put a lot on here and don’t want to overdo it right now)

If anybody on here has gotten Andymark Swerve and steer to properly drive could we take a look at your code.

Anymore questions about our setup feel free to reply, and we’ll try to respond as quickly as possible.


1 Like

Can you share your code? I haven’t used those modules, but I’d take a look and see what’s up.

1 Like

@SeanSun6814 Not sure if you’re still active here, but a team following 0toA could use some assistance!

I’ll shoot him a text too :slight_smile:

1 Like

The only code I have to share is in LabVIEW, but there should be no reasons for you to switch languages here. However, it’s difficult to help you as there’s not enough information to identify the problem.

This isn’t particularly informative:

but it’s your only description of the problem. Without your code, that’s all we have to go on.

1 Like

What’s actually happening?

Have you just not tuned the controller for rotation?

Better description or even better is video of the issues.

Code on GitHub?

Has anybody gotten them to run properly

Yes, they work fine. There may be a little more “play” in the rotational gearing and the modules are overall higher than some of the newer mechanics, but rest assured that they drive just fine.
There are, however, several things that need to come together with any swerve drive, so best go step by step. Implement PID control (just P may suffice) for the rotation. Read the absolute encoder and have the module rotate to the desired angle within one degree. Figure out what offset angle you need per module to point each module “straight ahead”. Then control the speed of the driver, using feed-forward, to be at desired speeds. Then put that together, for example using the edu.wpi.first.math.kinematics.SwerveDriveKinematics, which you feed the desired robot moves and it tells you what angle and speed to run on each swerve module.

We have switched to AS5600 angle sensors but we did have it fully functional with MA3s. We are using position control on the turning motor controller. The MA3 output is sent to the Sparkmax (we are using talonsrx for our pg71s) analog input. The input is 0-3.3v and the MA3 is 0-5v (really 5*0.8 if I remember the datasheet) so you will need to electrically scale that voltage down. You can use a voltage divider, which is a pair of resistors. Connect to usb and open the spark max client and make sure the readings are as expected. Basic position control code is here but you need to adapt for brushed motor:

Once that works you can integrate with the swerve drive code of your choosing. @nstrike offered us to try their library in another discussion.

I am happy to detail each of these steps but I was not sure if you want to go down the same route. There is nothing wrong with sending the encoder output to the rio but I prefer the motor controllers do all the work. It makes life easier.

1 Like

Yeah sorry, was going to include this in the original post but I guess we forgot to.

I started in your SwerveModule to see if everything looks right.

  1. Do you have the PG71 built-in encoder wired to the Spark Max?
  2. Are you sure the PG71 encoder is 4096 counts per revolution? I think it should be 28. The AndyMark page says its 7 pulses per revolution, and 7 * 4 = 28.

7 counts per motor rotation * 71:1 gearbox * 48:40 swerve and steer ratio (seems weird to me) = ~ 414.166 counts per module rev.

So 4096 can’t be right …

(Also this was a quick and dirty lookup, I could easily be wrong with that ratio or forgot something)

We actually are pivoting to absolute encoders instead of the ones built into the PG71 gearmotors. Specifically we are using the MA3 Absolute Encoders from Andymark, you have any idea how we can go about changing the code to match that setup? trying to rewrite it so the “turningEncoder” variable references the absolute encoders positions instead of the PG71’s

That’s a 10bit encoder to my knowledge so there are only 2^10=1024 counts/rev of encoder.

As far as my (very limited) knowledge goes it may be easier to send he encoder feedback to the spark max, although you will need the analog input equivalent for spark max of (input port/ analog board, not sure exactly how to wire off of the top of my head)

Talon implementations have required this or similar in the past.

… ok, didn’t know roborio is going to output a 12 bit value

GetVoltage() will give you the voltage in 0-5v.

1 Like

I second @Skyehawk’s suggestion to connect the MA3 encoder to the Spark Max. This way you can run the steer PID on the Spark Max. If your only encoder is connected to the roboRio, you will have to run PID on the rio (this is how your codes is set up now.)

This post provides the information you need for wiring the encoder to the Spark Max. You have a couple break-out board options: the REV SPARK MAX Data Port Breakout Board that @Skyehawk mentioned, or the CTRE Talon SRX Analog Breakout Board (I have successfully used this to connect a potentiometer to a Spark Max, it should work with your encoder too.) Connect the encoder to 5V, GND, and ANA.

If you aren’t open to rewiring, you probably want to start by deleting the turningEncoder from your code and use your absoluteEncoder every place for the turning position.

1 Like

yeah we are working on replacing turningEncoder with absoluteEncoder, but now we need to find new Methods for certain places in the code since they don’t have the exact same ones…

for Example… this doesn’t work anymore because .getVelocity isn’t a valid method on AnalogInput’s

public double getTurningVelocity() {
    return absoluteEncoderReal.getVelocity();

Oh yeah, that’s a tough one. I think you’ll have to calculate the velocity.

If you connect the encoders to the Spark Max you could call SparkMaxAnalogSensor.getVelocity()

got any ideas on how to go about writing or finding a method for this one?


.setVelocityConvertionFactor isn’t working either…

The conversion factor is the number that is multiplied by the encoder reading to convert to your unit of choice.

The encoder has to be 1:1 to the wheel, so there’s no gearing (you might want to confirm this, if it turns more than once per revolution of the wheel, you need to change something mechanically.) The encoder gives a reading of 0-5v for one revolution. One revolution is 2*PI radians. To work in radians, the conversion factor would be ((1/5) * (2 * PI)).

We are a rookie team who is in pretty much in the same position as amosbessler and are hoping we can get a little help.

*We replaced the CIM motors with NEO Brushless Motors.
*We kept the PG71 Gearmotors as the steering motors connected to VictorSPX and are using MA3-Absolute Encoders wired to the Analog pins on the RoboRio and are using them as AnalogInput.
*We have the math figured out to get an angle reading off our MA3 Encoders
*Our code is at: drivetrain/main/java/frc/robot at main · Arcbound49/drivetrain · GitHub

We have been following this thread and from what we can understand, we are pretty close to getting it figured out. Our problem is that when we turn the turning motors, the turning motors stutter severely. We also have an issue where subtracting a constant from angle position to get our motor offset will yield inconsistent numbers for example, if we are getting a reading of 233 degrees with our drive wheels straight forward, when we subtract 233 for our offset, we will get a reading of -500 degrees.

Thank you for any help.