After a lifting arm is moved to a position, it slowly falls down. The “stopping” for the arm motor is set to “hold”. I printed the motor position to the brain screen, and it slowly decreased. I can re-position the arm in code, but the arm goes up and down slightly while it should be holding steady. Is there a way to prevent this?
Look up proportional control on the forum. Also PID will do a similar thing, so please research that too. Both will counteract the arm falling.
Is your arm rubberbanded?
I have a feeling this is an issue with code then, but remember the motor has a torque limit. It can’t hold a position if it doesn’t have enough torque to do so.
This is what the
.hold() function uses to maintain position. No need for anything custom in this case. But if you really wanted to, you might as well go custom.
Yeah I know that Mvas, that is why it’s really odd it isn’t working. I have had a similar experience with the hold where it doesn’t work really well, but I don’t know what causes it. I figure custom control is the best when you can’t use the standard system. I think torque is the issue because when we saw a motor do something similar it was with our 2 bar and our tray (mainly the unbanded heavy 2 bar).
Is this with a VexIQ motor seeing that this is posted in the IQ section. IQ motors will hold their positions and resist movement if brake mode is set to hold.
Don’t know how much weight is on the lift, but my guess is that this is mechanical and not with software. Have you checked with a different motor? With IQ motors you don’t need to write a custom PID to deal with a motor that isn’t holding its position.
I am using the Rise robot, the new build for the Rise Above season, which uses a rubberband to help with the lifting arm. The falling behavior is not new. I noticed it throughout last season whenever I used VEXcode IQ Blocks. It does not happen when I use RobotC, RobotC Graphical, or RobotMesh. The arm slowly falls down. It is as if the motor internal code doesn’t keep track of where the motor position is supposed to be, but rather where it has been in the recent past, and 1 or 2 degrees is within tolerance from its recent position, so the arm slowly falls down. In the code I have set the max torque for the arm motor to be 100%. I have written my own proportional code to handle this situation, but I coach elementary school teams and some of the programmers will need to start with the basic commands.
Bit odd. Read Jpearman’s response on this thread Spin for changing brake mode?
Are you using the spin commands? He indicates that the spin to and spin for commands always end with a brake hold, and that’s a function of the motor itself and not built-in functions in VEXcode. So, a bit odd that this is not working in VEXcode but works in RobotC.
@JenniferVEX Post the project you are using or an example project that exhibits the same behavior and we can take a look and see what’s happening.
Attached are two code examples. One, RiseIfFalls, causes the arm to slowly fall. The other, RiseEventNoFall, does not have this behavior. Both programs do not stop the MotorArm motor at all, actually, so I guess setting the MotorArm stopping to hold doesn’t matter? The arm velocity controlling code sets the motor velocity and the motor is always spinning, as in the initialization. This is done to allow the programmer to change motor position/speed by changing the motor velocity. When whittling down my program to focus on the arm falling issue, I found that using an if-then statement to set motor velocity caused the arm to slowly fall, but using events prevented this problem. When either program is running, I press the LUp button to lift the arm to about 240 degrees, then release the LUp button. The arm slowly falls when running the RiseIfFalls program, and stays in position, more or less, when running the RiseEventNoFall program.
Incidentally, note the disabled command in the Initialize block. I would like for this to work so that when the arm is initalized (brought down from any raised position and the position reset), it takes only as long as needed, but this has never done what I expected. I assume that < MotorArm is spinning? > is TRUE when the motor is spinning and FALSE when the motor is not spinning. Is my assumption wrong here? How is < MotorArm is spinning? > used?
RiseEventNoFall.iqblocks (17.4 KB) RiseIfFalls.iqblocks (15.0 KB)
Ok, I see the issue, but it’s complicated to explain. The simple answer is that sending velocity 0 (or stop) in a loop causes the motor to reset some internal control parameters. Your event based solution only sends stop to the motor when a button is released, the loop based approach is constantly sending stop. The reason this happens is due to customers wanting to use the other motor brake modes, coast and brake. Anytime a zero velocity is sent, we have to tell the motor to go back into that mode. Anyway, I will see what we can do to improve this situation, there’s a VEXcode release planned for later this month, hopefully we can get some improvements for this use case into that.
Thanks for uploading the code. The torque is set to 10% on both sets of code. That may not be enough torque to keep the lift in position depending on the weight of the lift.
Also, between the RiseIfFalls and RiseEventNoFall, the NoFall always sets the motor speed back to 0 (always as part of the else condition). Essentially putting the motor to brake hold.
However, in the SetLiftPosition function of the RiseIfFalls, on the outer if/then condition statement there is no set motor speed to 0. It just relies on the set motor arm velocity statement that runs immediately to set the velocity to the value of LiftSpeed, which is 0. However, I don’t know if that’s the same thing as Set LiftSpeed to 0. The NoFall explicitly sets the LiftSpeed to 0 after each else statement to lock the motor in hold mode.
Thanks for this explanation, jpearman. Looks like programming using events is what I will use for now. Or, I may set the velocity of the arm only if the LiftSpeed variable value changes, especially to 0.
Or… add in code to put your motor back Into the intended mode right after setting speed to 0.