Brain: VEX IQ
Software: RobotC (code)
Game: Ringmaster
Our robot has an arm that goes up and down. I have a Bumper Switch at the “top” and “bottom” positions to cause the ARM motor to stop (so the motor is not strained).
The problem I’m having is the Bumper Switches do not work 100% of the time and the robot hangs in TeleOp mode because it’s waiting for the Bumper Switch to “activate”.
I am having difficulties in writing a routine that will stop the motor based on information from the Smart Motor (ie. not using feedback from the Bumper Switches)
I’ve tried:
getMotorCurrent (but this seems to be a moving target as the motors warm up)
getMotorSpeed
getMotorZeroVelocity
My goal is to move the arm as far as it will physically go, then set to the MotorBrakeMode to Coast so it does not put strain on the motor. The way the robot is built, both the “Up” and “Down” positions will stay at rest without motor power (I don’t need the motor to hold the position).
Here’s my “non-working” program so far… (within a “repeat forever” loop)
// ARM UP
while (getJoystickValue(BtnLUp) == 1) {
setMotorBrakeMode(ARM, motorHold);
setMotor(ARM,-100);
if (getMotorZeroVelocity(ARM)==1) {
stopMotor(ARM);
setMotorBrakeMode(ARM, motorCoast);}
}
// ARM DOWN
while (getJoystickValue(BtnLDown) == 1) {
setMotorBrakeMode(ARM, motorHold);
setMotor(ARM, 100);
if (getMotorZeroVelocity(ARM) == 1) {
stopMotor(ARM);
setMotorBrakeMode(ARM, motorCoast);
}
}
Is the bumper being hit squarely? I’ve seen a lot of bumpers fail when they’re skewed, especially when used with a long bar attached to them. Meanwhile, I haven’t seen them fail when hit squarely. So it could be an issue of the positioning of the bumper.
As for the programming, if the motor is still running and the arm isn’t going anywhere, is the motor really not moving at all? Or is it twitching very, very slightly. This could make == fail. I would go with ≤ instead, which would mean looking at the speed rather than just if the velocity is zero.
But the bigger problem looks like it’s in the while loops. Consider what happens if you keep holding a button down. You keep cycling through your while loop. So when you hit the top, you’re telling it to go -100, no coast, no -100, no coast, … You’ve also disabled all other controls because you’re in this while loop. You really want to do it with this structure:
while(true){
if(getJoystickValue(BtnLUp) == 1){
// do stuff
}
}
You cycle through all your button/stick checks and set motors based on what it finds. That way you can be using several things at once.
Within the if statement, you can create a second if statement based on reaching the limit. Or you can make two parts to the if statement, once checking the button and one checking if it’s all the way up.
I know this is a reply to an old post, but I have a nice elegant solution. We are using modkit, but I figure you can adapt our method.
First, we always start the code running when all arms/etc are in the fully ‘down’ position. Then we simply watch the rotations for the motor. When they exceed a certain value, we issue a stop command.
We also check the rotation number before starting a motor. So the arm can start at the bottom, travel upward, be stopped by the rotation counter, and you CANNOT restart it moving upward. It will only respond to ‘down’ commands. Same happens at the bottom of travel but in reverse.
The limit variable:
0 (arm less than 0 degrees, happens when going down… it always bypasses the stop a few degrees)
1 (arm between 0 and 510, or between lower and upper bounds)
2 (arm over 510 degrees, happens when going up, overshoots the mark a little)
When
limit = 0, arm will only go up
limit = 1, will go up or down
limit = 2, will only go down.
Like you, we used to use limit/bumper switches. This works so much better. Easier to adjust. Less complicated. Etc.
You need to display the rotation degrees to the screen. Will help you when finding the degrees to use. We counted the number of times the shaft turned to get in the ballpark.