So we have an arm that is raised using sprockets and a chain. We have a CIM motor driving it and it is on a Spark. The motor is heavily geared down so as to have as much torque as we can have.
We want to code a button on the controller that toggles a command that would keep the motor going at a reduced speed whenever a the arm is not being raised, so as to keep the arm in place.
The issue with the reduced speed/voltage is that the torque needed to hold the arm in place varies along with the cosine of the arm position. The right solution is to add an encoder or potentiometer and use a PID controller.
I am a Mechanical Engineer, so I’m biased, but I’d first look at a way to counter-balance your arm so that without any motor power it stays in the same place, be the a literal counterweight or springs of some kind.
Beyond that you could calculate the torque needed by the motor (find the mass of the arm, find the distance the center of mass [the point you could balance it on a pencil] is from the sprocket, multiply them together to get the torque at the sprocket, divide by your gear ratio to the motor, and cross reference that to a graph of motor torque vs power) … or you could just find it out by trial and error (start at 10% power, does it stay? if yes increase by 10%, if not decrease by 5%, repeat until it stays put).
Do note that how far the arm is rotated (e.g. level with the ground vs pointing at the ground) will change what the motor power will need to be. If you want to do it right you’ll need some kind of feedback (encoder/potentiometer) that will tell you where the arm is, so you can do math and calculate the needed motor power.
The third option is to put a worm gear (like the window motors have) as one of your stages. They’re non-back-driving so gravity pulling on the arm will not be able to turn the motor, but the motor can still move the arm.
One additional thing - it’s possible to estimate the motor’s speed if you have some measure of the current draw (preferably a Talon SRX or Spark MAX’s sensors, the PDP’s is inaccurate and laggy), but that’ll require some mathematical modeling and more work than just slapping a pot on there.
One way to find the power is to find a power that would keep the arm up when it is parallel to the ground and then to find the power for different angles just multiply by the cosine of the arm’s angle.
Someone else will have to say how to code it, you’ll probably want to say which particular brand/model of encoder you have, but for mounting it: it depends on which type you have. Encoders have some trigger mechanism and a sensing mechanism.
Magnetic encoders rely on having the sensor a precise distance away from a fancy magnet magnet (that comes with the encoder) which you stick on the thing you want to rotate, co-axially.
Optical encoders usually have a disk that you need to run a shaft into/through and the sensor is in a housing around it.
In either case you’ll have one part that rotates with your arm, and the other is stationary (or for an arm joint they’ll be on different arm sections). You’ll want to read the manual for whatever model you have since it’s written by the experts.
Personally we’ve moved to Versa-planetary integrated encoders. Reason being that as long as you’re using a versa-planetary gearbox you can simply install them like any other gearbox stage, which is way, WAY easier than most of the other options.
What motor controller are you using? There’s two kinds of SPARK controllers out there…
I’m assuming you’re using a quadrature/optical encoder.
Simple PWM controller (old SPARKS, Victors): Plug the encoder into your roboRIO’s Digital IO (DIO) and create a new Encoder object using the channel numbers that the encoder is plugged into.
SPARK MAX and Neo: Not sure for myself (he said with a NEO drivetrain), but there are examples. No separate hardware, the encoder is in the motor itself.
SPARK MAX and CIM: No idea other than it involves a breakout board like a Talon SRX.
check this thread out. It directly relates to what you want to do. I have put up our team’s code for this years off season event that controlled the wrist on the robot and it should work about the same.
Few things that we did that helped control an arm.
1- Surgical tubing to counterbalance the arm- The arm basically was held at a 45 degree angle without providing any power to the motors.
2- a brake on the axle that the arm rotated on- Whenever the arm rotated to a set position on encoder the brake was activated. If you are using pnuematics already I would recommend this, it was much easier than I thought it would be.
We’re doing this with a COTS bike disk brake. Works like a charm. No need to drive motors to hold the arm, setting the brake locks the arm in place real good.
FYI - quadrature is the operative thing you actually need for the application (allows direction sensing). Optical specifies the internal technology for doing the sensing. Though it’s super common, it’s technically not relevant to the specification.
We manually had a spark max follow a talon srx and used motion magic to keep our arm positions. We used another thread on the roborio to send the signals to the spark max quickly after we tell the talon srx. We get voltage output from the talon srx and send that to the spark max (spark max’s internal following of a talon srx is buggy) and it does really well.