# [FTC]: Spin Motor Wind Down: Programming

Does anyone have any creative ideas about how to get our launch motors to wind down slowly instead of just crashing to a stop.

When I release button one or one of the joystick controls I’d like our launcher to not just crunch to a halt which is painful to hear and I’m sure is doing damage to the motor and the gears.

Thanks!

I would use this

if(joystick.joy1_y1 == 0 && motorspeed > 0)
{
motorspeed = motorspeed - (desired decrement)

}

it’s simple and simplicity is the key. So what is basically happening in this code is that if you’ve let go of the left joystick and the motor hasn’t stopped then it will decrease the speed then the rest of the code will execute then the process will repeat. The only tricky thing about this is the decrement will have to be small because the code will repeat almost immediately.

Thanks. Make’s sense in C but not in labview.

Thanks though.

jamie_1930, while your approach is indeed simple, I do not believe it would ramp down the speed over a long enough period of time. I would suggest you refactor your strategy into a separate task which could employ a wait statement inside of a loop until the speed reaches zero. This would allow you to properly slow down the speed over the course of several seconds. Also, I imagine you would likely want to employ the same approach to ramping up speed.

This is assuming you are not actually trying to control the speed of launcher motors interactively with an analog stick… which I would also not recommend as it would be very difficult to shoot any distance consistently other than full speed and you still run the risk of stopping the motors hard.

There is a (poorly written) article I put first forge that might help:
http://thinktank.wpi.edu/article/140

Page 5 shows that code implemented in labVIEW.

l0jec - I’ve never competed in / programmed for FTC, but I have used this method many times in FRC. It is a quick’n’dirty method that can be effective in a pinch.

How often does the FTC code run? I’m used to 40/50/200Hz for FRC.
Does it do floating point or just fixed point?

This was the main concern I had with implementing that code although this should work fine. Just make x (x = iterations ; creates the needed pause) the right number. (here it’s 1000 just for the sake of example)

if(joystick1.joy_y1 == 0 && motorspeed > 0)
{
x = x + 1;
if(x=1000){x = 0; motorspeed = motorspeed - 1;}
motor[shooter] = motorspeed;

}

if(joystick1.joy_y1 != 0){motor[shooter] = ((joystick1.joy_y1 * 100) / 127);}

or if your using a button

if(joy1Btn(1) == 0 && motorspeed > 0)
{
x = x + 1;
if(x=1000){x = 0; motorspeed = motorspeed - 1;}
motor[shooter] = motorspeed;

}

if(joy1Btn(1) ==1){motor[shooter] = 100;}

that should work much better

**jamie_1930: **

Yes, that should do the trick as well. You’d need to add a little more code to reset your runtime counter (x) once it hits 1000 or if the launcher is reactivated and do some testing to find the optimal limit. Even though it is just sample code, a team using the analog sticks would need to also compensate for a deadzone in your first example.

One last note on this is that my students observed a difference in how smoothly the shooter mechanism came to a stop depending upon whether or not they floated the motors. If braking was enabled (the default) then the mechanism would slow down until about 20% power and still stop fairly hard due to the motor attempting to brake (maintain speed) at low power and not overcoming the torque to keep driving the gears. If they floated the motors first, then the mechanism would slow down nice and smooth all the way using its own momentum.
Test and experiment; YMMV.

EricVanWyk:

ROBOTC makes it easy to spin up separate threads (tasks for the NXT) where you can use wait statements without pausing your primary control loop code (located in the main task). In this model, you shouldn’t care how fast the processor can execute your primary control loop and have to guess a counter limit, because you can explicitly set how many milliseconds you want to wait between stepping up or down power to a motor in a separate task. No guessing and the code will be much more optimized anyway.
Yes, ROBOTC supports floating point calculations.

we had the same problem. however since we found out how much damage it can cause on the motors the hard way at a competition, we did a quick and dirty fix. we set it to an idle speed. this way the motors always ran. sped up nicely, and slowed down nicely.only down side was everyone thought we did something wrong in the code, and it would occasionally spew out a ball or two because we had the idle speed to high.

i think the nicest solution would be to turn of the brakes on the motors some how. although i don’t know how you would do that.

In ROBOTC, there is a global variable which controls this for all motors. You should be able to set it to true/false to enable/disable floating at will. However, from my student’s experience it can be a little buggy with the Tetrix motor controllers, so make sure you test.

``````//float motors
bFloatDuringInactiveMotorPWM = true;

//brake motors
bFloatDuringInactiveMotorPWM = false;
``````

we tried that. the motors did some very odd things. the motors pretty much went haywire when we did this.

but we don’t really want to turn off the brakes for all the motors. is there a way to set just 2 motors to float like in NXTG?

Your experience seems to match ours. One of my students came up with a possible fix (hack) which appeared to prevent their drive motors from flipping out when they wanted to coast their shooter motors. I’ll check with him to see what it was and if it is a viable workaround; if it is, we’ll post it.

thanks. that would help a lot.

in the mean time something like this might help for anyone else trying to keep there motors alive:

``````int motorSpeed = 100;

void powerDown()
{
if(time10[T1] > 10 && motorSpeed > 10)
{
time10[T1] = 0;
motorSpeed --;
}
else
{
motorSpeed = 0;
}
motor[shooter] = motorSpeed;
}
``````

i haven’t tested this either, but it is pretty simple and based off of previous functions from last year which worked consistently.

I talked with the student who had come up with a potential workaround. It sounds like he was adjusting the bFloatDuringInactiveMotorPWM before setting any motor speed. The reported observation was that the bFloatDuringInactiveMotorPWM was only read/applied when setting the power to a motor, not after. So if you wanted to only coast a single motor, you had to set bFloatDuringInactiveMotorPWM to true just before setting the power on that specific motor and then set it back to false before updating any other motors. Any other motors with power already set when the flag is changed do not get affected.
The biggest challenge I see with this type of workaround (assuming it works at all) is if you are setting motor outputs from different tasks.

I did not test this myself, but wanted to pass it along as promised.