ROBOTC has PID to control your flywheel

So I had a face palm moment earlier this evening. ROBOTC includes PID for velocity control in V4.XX. It’s really intended for use on classroom robots to allow them to drive in a straight line, but (in theory) it should be possible to use this on flywheels. Here is an example program.

#pragma config(I2C_Usage, I2C1, i2cSensors)
#pragma config(Sensor, I2C_1,  ,               sensorQuadEncoderOnI2CPort,    , AutoAssign )
#pragma config(Motor,  port2,            ,             tmotorVex393HighSpeed_MC29, PIDControl, encoderPort, I2C_1)
#pragma config(Motor,  port3,            ,             tmotorVex393HighSpeed_MC29, openLoop)
#pragma config(Motor,  port4,            ,             tmotorVex393HighSpeed_MC29, openLoop)
#pragma config(Motor,  port5,            ,             tmotorVex393HighSpeed_MC29, openLoop)
//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//

task main()
{
    // Motors on ports 3, 4 & 5 will follow the motor on port 2
    slaveMotor(port3, port2);
    slaveMotor(port4, port2);
    slaveMotor(port5, port2);

    // Driver control loop
    while(1) {
      // Two different speeds.
      if( vexRT Btn8U ] == 1 )
        motor port2 ] = 50;
      else
      if( vexRT Btn8R ] == 1 )
        motor port2 ] = 100;
      else
      if( vexRT Btn8D ] == 1 )
        motor port2 ] = 0;
        
      wait1Msec(20);
    }
}

Four motors drive the flywheel, you can see I call a function called slaveMotor to slave three of the four ports to a master motor that has an IME. That motor has PID turned on the the motors & sensor setup dialog, now when you send values to the motor the actual motor power is controlled by ROBOTC. This works well for drive motors, I have not tested it on a flywheel, it does allow “headroom” so it may end up that the flywheel does not spin fast enough but perhaps a team with a working flywheel might like to give this a go.

The PID constants may still need tweaking, you will find them in the motors & sensors dialog as well (turn on menu level “super user” first).

Let me know if anyone has success with this.

Mote explanation of ROBOTC PID here.

http://www.education.rec.ri.cmu.edu/products/cortex_video_trainer/lesson/3-6IntegratedEncoders2.html

2 Likes

I understand this is designed for an IME, but is there a way to use a quadratic encoder to do this? I would like to try it on my robot, but if i cant use an encoder i will have to replace one of my motors with an IME. (may take some digging aroind but i know i have a few). And so your saying that RobotC already has all this built in, we simply just need to turn it on in the motor and sensor setup and then adjust the constants which are under the menu on the left side of the RobotC window? I watched the video but it did not explain where to find it in the code (this may be a dumb question, sorry! Being a progeamming noob, i might not be the best person to try this either but i would like to give it a shot)

Pretty sure it only works with IMEs. I will look into whether a quadrature encoder will work tomorrow. If it does, then it probably would need to be on the motor drive shaft not on the flywheel.

2 Likes

I am pretty sure the built in PID only works with IMEs. It is entirely possible I am wrong but I am pretty sure I took a look into it over the summer.

If you put


motor port2 ] = 100;

Are you sending 50 power to your motors? Or 50 rpm?

If it is sending 50 power, won’t the velocity of the motors be affected by battery levels?

50 power. Yes, battery level will make a difference. But since you start each match with a fully charged battery, it will be a minor difference.

What are the default PID constants? or are there any? i see the menu for PID, but how can i tell what the constants are or how do i change them? is this really as easy as it looks, where you just turn on the PID control and it does the rest on its own?

Actually neither, it’s an arbitrary speed where 0 is stopped and 100 is fast. The actual raw power level sent to the motor will depend on the load seen by the motor. Look in the debug window at the value of “PWM power”, that’s what is actually going to the motor.

This functionality, as I said in post one, was designed for making a robot drive in a straight line (ie. making left and right weeks travel the same distance), it may or may not work on a flywheel.

The default constants are visible if you click on “More” in the PID settings tab (remember, super user menu turned on). It’s sort of complicated to explain but there are system defaults that all ROBOTC programs will share and program specific settings. Double click on one of the list box rows to change for that motor.

2 Likes

IME only with the current versions of ROBOTC, I can fix but probably missed the next release unfortunately.

2 Likes

When i go to the super user menu on the left, i clicked on PID and get a list of things, including something along the lines of mtrPIDKp] or mtrPIDKd]. Are these not just there for reference? Clicking on them does nothing, but to my knowledge those are there so you can read and copy them into your code and then use them. So im assuming this isnt the pid settings tab you are refering to, so any guidance on to where that is?

In motors & sensors setup, select the PID tab.
pid_1.jpg

This shows the motor port you have enabled PID for.

Click on more to show default settings, they are different depending on motor type and which port (with or without MC29) they are connected to.
pid_2.jpg

Double click on either your specific port or a default setting to edit.
pid_3.jpg

2 Likes

I just tested this on our robot, and we scored 20/24 shots with barely any tuning. Before we were making roughly 15/24. Thank you so much for all the help! For reference, we have a four motor 16:1 turbo single flywheel, and we used an IME and slaved the other three launcher motors as stated. It was very simple to do, and i would defiantly recommend it other teams. After a long struggle with the TBH and other PID codes always overshooting, this is definitely our new solution. Yet again, thank you Jpearman!

1 Like

… So it copies the power of the port 2 and sends the same power to port 3

Yes, it copies the motor value from port 2 to all the other “slave” ports. This is because the motor power of port 2 is always changing because of the integrated PID and it then sends the correct motor power to the rest of your launcher motors so that you don’t have to have four separate IMEs.

Sweet

Just wondering, how was your firing rate?

My firing rate was somewhat slow, probably only one ball per second. I believe i could have sped that up with a higher P value? does that sound correct to anyone? I think in order to increase recharge time i would need a higher P value and then increase my D and I values accordingly.

EDIT: I am also aware that my flywheel has a bit too much compression and fails to make a nice “swish” sounded when balls exit, it sounds more like a slip gear or nautilus gear launcher! if we lower that compression rate to a more proper amount it should really improve our recharge time. at 80/120 motor power we can fire around 2-3 balls per second. there is definitely room for improvement, and it is not fully the codes fault that it can only shoot 1bps at the moment

what you said about increasing P values should be true

Now that I went and messed around with the inbuilt PID of RobotC, I stumbled across a few functions that I do not understand:

Firstly, what does


bUseVexI2CEncoderVelocity

do? And how exactly do you use it?

Secondly, I am confused as to how to use the


nMotorPIDSpeedCtrl]

function.

It would be great if anyone were to clarify my doubts. Thanks :slight_smile:

Perhaps you are talking about something more advanced than I have looked into yet, but when i worked with mine i never left this window here with the exception of adding the master/slave program. I never actually had to call on any of these functions to get the base of it to work