I am currently programming an autonomous for my flywheel robot and ran into an issue. While indexing balls, I need the flywheel to already be running at full speed before I index. How do I tell the flywheel to rev up to full speed, and not allow the intakes to spin until it’s up to speed? Once again, I am using C++ for Robot Mesh Studio.
Add a while loop before the index spinup that only exits once the motor has reached its target RPM
How would I do that exactly. Sorry, I’m not a programmer at heart.
Well here is some pseudo code.
blah blah spin flywheel motor;
while (flywheel velocity < target velocity){
wait(100 msec);
}
blah blah spin indexer;
Of course this isn’t real code but the logic stands.
It would look something like this:
//flywheel spinup
while(motor.speed < targetSpeed){
wait(100,ms);
}
//index spinup
so then you’d just need to replace motor.speed with however you want to get the flywheel speed and fix any differences between this and how RMS does vex C++
It won’t let me select one as the solution. So, thank you both for the help. It’s greatly appreciated!
Actually, I plugged everything in and it still says there is an issue. Can either of you help me point that out?
while(Flywheel.rpm < 600)
{
sleepMs(100);
}
Intake.rotateFor(10000,rotationUnits::deg,100,velocityUnits::pct);
What line is the error on and what is the error message?
On the line that says while (flywheel.rpm < 600):
Here is the error code:
main.cpp(64:20): error xxx: 'class vex::motor' has no member named 'rpm'
Flywheel.rotateFor(2000,rotationUnits::deg,100,velocityUnits::pct);
while(Flywheel.rpm < 600)
{
sleepMs(100);
}
Intake.rotateFor(10000,rotationUnits::deg,100,velocityUnits::pct);
Got it. I am not familiar with RMS but it looks like its just the vex namespace. you need to do something like this.
Flywheel.velocity(velocityUnits::rpm)
This is the proper way to get velocity, rotation, temperature and such.
motor.measurement(measurementUnits::unit)
replace measurement with what you are trying to find and unit with the proper unit.
Okay… so now I have this:
Flywheel.rotateFor(2000,rotationUnits::deg,100,velocityUnits::pct);
while(Flywheel.velocity(velocityUnits::rpm) < 600)
{
sleepMs(1);
}
Intake.rotateFor(10000,rotationUnits::deg,100,velocityUnits::pct);
And it compiles fine, and it runs, but it doesnt switch to the intake function and the flywheel just stops running. Any suggestions?
Flywheel.rotateFor
is a “blocking” function: execution will not move on from that line until the motor reaches the target. (It’s meant for drivetrains, arms, and such, where this is a useful property) Once it reaches that target, it stops the motor, then moves on to the next line. Where, of course, it gets stuck, because the motor rpm will never reach 600, because the motor is shut off.
- Consider using a different method call, such as
spin
. - If a robot is acting strangely, or you find yourself confused about program flow, try adding some diagnostic
printf()
calls to your program. That function can print text or sensor values back to your computer over the usb cable. Here, aprintf("Flywheel speed: %d", Flywheel.velocity(velocityUnits::rpm));
before your while loop would have printedFlywheel speed: 0
, and given a valuable clue to what was wrong. while(Flywheel.velocity(velocityUnits::rpm) < 600)
may not work, depending on the friction of your flywheel. V5 motors are not infinitely powerful, if you put too much load on it, it will not make it to 600 RPM.
Cheers, Sam.
Adding on to this. You probably want to print the flywheel motor velocity on your screen and check in user control what the actual max velocity is of the flywheel and then make your target value slightly lower than the max value.
And one more thing. I am assuming that the reason you used rotate to in the first place was that 2000 or so degrees was the amount needed to shoot the ball. I would suggest spinning up your flywheel as soon as auton starts and then using your indexer to control when and how many balls are shot. Firstly, this eliminates the need to spin up the flywheel over and over again so that you are ready to shoot whenever and secondly, allows for much greater control over when the balls are shot.
Okay… so here’s the closest I’ve gotten to a “working solution” in my opinion.
Flywheel.rotateFor(2000,rotationUnits::deg,100,velocityUnits::pct);
printf("Flywheel speed: %d", Flywheel.velocity(velocityUnits::rpm));
while(Flywheel.spin(velocityUnits::rpm) < 550)
{
sleepMs(1);
}
Intake.rotateFor(10000,rotationUnits::deg,100,velocityUnits::pct);
Now it seems as if the issue is both with the printf
function isn’t working and the flywheel getting up to speed. I am using a 600RPM motor 1:5 for the flywheel, so it takes less that a second to reach max rpm. It is not switching to the next function though of indexing.
Like Sam said, rotateFor is also blocking so the code will not move on to the printf or the while loop until the flywheel motor stops. I would recommend using spin stead of rotate for, or if you really want the flywheel to only spin a set amount of degree add a “false” parameter after pct in the rotate for command. This will make it non blocking but I do not recommend this. Also side note you will have to tell the motor to stop if you use spin because it will not stop otherwise.
Also if you use degrees you will need a much higher number than 2000 because at 600 rpm in 1 second you already surpass this value. I strongly recommend using the spin command and just leaving the flywheel running.
This code does not appear to properly incorporate any of the lessons Sam, Deicer, or Cadaver were trying to teach you. It is still using rotateFor
twice after several people advised you against using it at all for this application, and the way spin
is used is incorrect as well. I’d recommend looking up the motor methods you intend to use on the documentation page for the motor class to see what they do and how they’re used.
My bad. I thought they meant to put spin within the while loop itself, not in the flywheel rev up before the while loop.
Okay, so, I’ve been trying to mess with this code quite a bit. And here’s what I’ve got to:
Flywheel.spin(600,velocityUnits::rpm)
while(Flywheel.spin(100,velocityUnits::rpm) < 550)
{
sleepMs(1);
}
Intake.rotateFor(10000,rotationUnits::deg,100,velocityUnits::pct);
Now I don’t know what the issue is. Any help or suggestions?