Curvature Drive Help

Hello. For an off season event my team has decided to make a basic robot without the help of mentors. So this is really my first time trying to program an entire robot without someone guiding me through every step.

One of the things our team is wanting to do differently is instead of using Cheesy Drive Helper is to try and switch to Curvature drive. In the simulation, however the values for our CANSparkMax aren’t changing when you move the joysticks on the controllers. We have our code divided into subsystems

CANSparkMax IDs are: 1,2,3,4
DriverController Port is 0

Here is our code: Hastebin: Send and Save Text or Code Snippets for Free | Toptal® Hastebin: Send and Save Text or Code Snippets for Free | Toptal®

Does that mean a mentor shouldn’t answer this? Genuine and serious question.


Yes, they can help, but I also wanna ask on here to see what other people recommend.

1 Like

Rock on. Just wanted to make sure.

I think whatever mental age Marshall is, he is technically a mentor. :kissing_closed_eyes:


Congratulations on your motivation and self-starting to do a meaningful project.

Your project is of interest to me for a couple of reasons so I took a look at it. Yet another partial code listing and that severely handicaps reviewers.

A trivial example that could apply to your problem is we only have your word for it that motors leader and follower have been correctly set up. If one is rotating the opposite direction of the other because you had an inversion sneak in, that could cause the symptoms. You’ll come back with “that’s not the problem.” Then we have to assume you are correct and then guess what else there is that we can’t see.

Assumptions can suck the life out of analyses!


As @SLAB-Mr.Thomas says, it’s hard to review your code when you only give us a little bit of it. You’re assuming the problem is in the fragments you’ve shown us, but I can’t see anything obviously wrong there. Often the problem turns out to be in a place you weren’t expecting.

When you say that “the values for our CANSparkMax aren’t changing”, what exactly are the status lights doing?

I see you have your own implementation of XboxController. Why? Has it worked in the past? Can you add logging in teleopPeriodic to record the joystick values being passed in?

1 Like

Also, technically, anyone helping in this thread is a mentor (as they are providing mentorship), whether they are a student or an adult.

1 Like

So you want no help and help at the same time? I’ll put some thoughts about my experiences programming FRC robots below, which you can read if you wish.

Suggestions Within

StackOverflow’s Question-Asking Guide is a really helpful resource for asking questions well and getting the best answers in an efficient manner. The problem though is that FRC is quite tricky since there isn’t really a good way to have an MVCE¹ and reading through tons of Java files manually to find faults is difficult (no one has an exact replica of your robot at home). What I recommend for programming is drawing stuff out and being really, really careful with magic numbers (this is why you see my code totally flooded with constants). In 2022 we ended up going with the “sysout every value we are confused about” route of debugging, which worked but I hope to find a better method of debugging for 2023.

¹Minimum Verifiable Complete Example

Another good guess of where things might have gone awry.

Yes, yes, yes to “sysout every value” but where so many people lose their way is assuming that they are NOT confused about things that actually could or are wrong.

Getting to the MVCE or at least very close involves all those sysouts to eliminate assumptions and is a great suggestion for OP to follow.

For OP’s learning benefit I’ll briefly summarize my guidelines on what to do with assumptions.
As I wrote my professional designs/analyses I’d put any and all assumptions that I was making at the top of the “paper” in the first section labelled ASSUMPTIONS.

By the time the paper was to be declared “done” I had to do one of three things to every assumption.

  1. Turn it into a fact (thus the suggestion to sysout everything)

Turn it into a documented limitation that is handled one of two ways

  1. enforced by code or mechanics such that the user can’t do it wrong
  2. administratively enforced by documentation (then I have to assume the user reads and follows the documentation)
1 Like

What type of motor is the SparkMax connected to? Your code says “Brushless”, so check that’s appropriate.

Does your PDP/PDH show any current usage by the motors?

That’s not what I meant by “no help from mentors” sorry for not wording that correctly. A better explanation is we have full control of our design and our code, they can offer help if we’re completely stuck but ultimately the challenge should be up to us.

Sorry for showing fragments of code, I kinda forgot GitHub existed for a second:

1 Like

We have our own implementation of the XboxController class because we have a nice shufflebord setup to where you can tune values such as deadzone, linearity, etc all on a front end.

It’s one of the few code I reused from our current robot.

Interesting. I don’t think I’ve ever seen a quintic used on a joystick before. Out of curiosity, I graphed your joystick transform (using the default configuration values) and compared it with raw abs_square and cubic. They’re much the same, but yours has a little kick coming out of the deadzone as it hits the minimum output.
I note that it would be possible to set a value on the shuffleboard that would effectively disable the joystick (e.g. deadZone=1). That’s why I think it’s important that you log the actual values you’re using for arcade drive. You might also consider emitting a warning if the deadZone is very large.

Edit: This is not related to your reported problem, but when you have a chance, consider using a less complex joystick model in combination with a feedforward calculation. That will incorporate things like minimum output (ks).

1 Like

“A common mistake that people make when trying to design something completely foolproof is to underestimate the ingenuity of complete fools.” ― Douglas Adams

…which is why it’s so important that you have good documentation, get your team to read documentation, or ideally get whoever is working with the code base familiar with “what’s going on” (this is made way easier with documentation). Code-enforced limits can still be used, but they should be documented as well so future users aren’t confused all like “hey, why’s there a max() or an abs() here?”

1 Like

I ran your current version of the code with a few problems but was only somewhat successful - that’s the good news, I suppose, and the bad news is I see the same result (no motor voltage) as you and even on my own one Neo/SparkMax flywheel simulation.

I couldn’t run your project directly due to error about something gradle missing so I copied your Java files into a new project. Your directory structure was a little different than my default so I renamed your imports and package since there aren’t many.

I discovered an idiosyncrasy (error maybe) on start simulation that the first time it doesn’t show the GUI selection list - nothing to see! The second time then the GUI and driver station list shows. This happens for all my simulation projects not just yours.

I only have one XBox so I cheated and used that for both operator and driver.

Of course, the first thing I did was add a print of what you send to curvature (the joysticks).

The bad news is I, too, see no voltage going to the simulated SparkMaxes. So I simplified and simulated one of my existing small projects of a single Neo/SparkMax for a flywheel. The real robot flywheel runs fine but like your simulation there was NO voltage going to my simulated motor.

I spent a few minutes looking for documentation or limitations on how to simulate SparkMax. Couldn’t find anything recent to help. The next step would be to try a RevRobotics example program and maybe a better documentation search since usually my errors are not reading the docs (and I do better than most).

Sorry no more time for awhile - maybe another day because today is “family” day to visit relatives and pick Pixie Crisp apples (yum).

I do wonder if this is the first time you have ever simulated a SparkMax or have you ever been successful in another project?

1 Like

Setting values directly to the SPARK Max seems to work, and our 2022 robot code updates the outputs as you would expect,but updating through a DifferentialDrive in this project does nothing.

Thanks. You did better than I. I couldn’t get either way to work in simulation. I tried OP’s diff drive and my flywheel was using set directly to the SparkMax.

I don’t know if this was changed in 2022, but in the 2021 version, the CANSparkMax did not support the simulation. We hacked it with this class:

and explicitly use the wrapper name for the constructor. It seemed to work for us. Note we did only implement the methods we needed, but they worked for driving in simulation.

1 Like

It was changed. Our RapidReact robot is able to simulate CANSparkMaxs perfectly fine, the thing that is different though is we are using DifferentialDrive and not Cheesy Drive Helper on this project.

For anyone curious, I printed a .tostring() of the CANSparkMaxes, MotorControllerGroups, XboxControllers, DifferentialDrive, and saw no error there. Furthermore, I was also able to manually change the voltage of the CANSparkMaxes using XboxController input without DifferentialDrive. At this point I’m thiking it has something to do with DifferentialDrive but I could be wrong.