Hi. I would like to use RobotC Graphical to program my robot to be driven by the controller, but I am having some difficulty with the options.
I have two motors on the rear of the vehicle, connected to port 1 and 6 in a standard configuration.
Port 10 I have connected a third motor that is controlling the steering arms that can swivel each front wheel right and left (similar to an actual vehicle)
The problem is that with only tankControl or arcadeControl I don’t know how I can simply program it to drive.
I want the left joystick forward and backward to link the back two motors together for forwards and backwards, and the left and right joystick movements to turn motor 10 (or failing that, the right joystick to turn motor 10)
Any ideas, or can it only be done in proper robotC non graphicaR
This is doable in graphical. You will tie the third (steering) motor position to the joystick value. You need to start the program with the steering motor centered, so you’d have defined zero angle.
Then, the simplest form of the program would look like this:
The steer line is created by using “Variable [Value]” block in graphical, you’d need to add a new variable there too.
You may need to play with the gain (how many degrees per joystick tick, 0.5 in my sample) and since you don’t have a differential gear (or do you), your driven gears would still fight a bit in the turns.
To counter that, you’d have to replace tankControl with your own implementation (again, using another variable from the joystick and distributing the power between the left and right motors based on the “steer”).
It’s a lot of fun, and you will only need one motor to run your back wheels. Build one of these and show it to the kids… The kids whose mouths drop to the floor… Those are the builders!
Sure, it took me a while to devise it, and I over-engineered it, as it is going to be driven by 50 children for 4 days over a Winter Camp. So it needed to be strong.
Sorry, it may be quite hard to build from these pictures, but its mainly using two 3x5 angle Beams and an 2x8 beam to tie it all together. The side with the motor on, I had to use two 1x3 lock plates to transmit the turning and on each hub I used two 1x1 chassis connectors with a large chassis connector to hold it together…it took a while, but works alright…Although no Ackermann Turning, but it works alright for low speed turns…
My code shown here works great to drive my robot and turn it (Thanks for the help) - but now I have a problem if the wheels are turned when the program starts then it (remembers) that position as ‘middle’ and then you cant easily drive straight…
I have tried to connect two Gyro sensors onto the robot, one on the body (target) and one on the steering arm (desired) and I want to run an initialization part, that will tu rn the steering motor until the two gyro’s match, then reset the steering motor’s encoder so that it knows that is the center…Any ideas… Thanks
I would just set the motor to the value of drive. As this is currently written, the speed is static. The car should move at different speeds based on how far the stick is pressed.
Use setmotor(motor,drive);
Also, the gyros are just nowhere as reliable as the integrated motor encoders. You could have a button that would reset the encoder to zero once the car is straight, and then another that would set the motor target to 0 when you want it to go straight.
If would be interesting to display the two gyros and the difference. Drive it around for a while, point the wheels straight and see how close they actually are.
I think you can tell I’ve had some trouble with the gyros in the past. I had a group that was using one for their autonomous and one time I opened up the device info and it was registering that the robot was turning at 2 degrees per second… and it wasn’t moving at all.
I love the mechanics!
For finding the center position, use a calibration procedure:
[LIST=1]
First set the steering motor to rotate one way and wait some time.
Reset the encoder.
Set it in the opposite direction and wait.
Read the encoder, divide by 2 -> range
Set steering motor target to this midpoint, wait till it gets there
reset motor encoder.
[/LIST]
Notes:
You can use the range from step 4 for adjusting the steering gain - to map the joystick range onto the actual steering range - no joystick movement would try to break your robot.
If you're worried about the calibration routine breaking your robot too, you can reduce the motor power during calibration. setMotorCurrentLimit be your friend.
You can even test the current limit flag to know you have reached the hard stop, no timing dependency necessary
Thank you Sankeydd, but from what I can tell, Tank control will not work, because if you move the left of right joystick at varying levels then the rear wheels will induce the turning (like a tank) and just push the turned front wheels and make the whole procedure invalid. The rear two motors must be locked and only move in unison (forwards and backwards) and the turning is only to be done with the turned front wheels. The two readings of the gyro’s are very near on accurate, besides, they play in the linkages in the front turning mechanism give a hysterisis of about 5 degree’s which is much more than the error I am seeing in the difference between the two gyro’s (about 1 or two degree’s at most) - so using the body gyro to set configure and turn the steering linkage until the gyro on the turning arm matches the body gyro, then resetting the turning motor encoder would be much faster (as sometimes the turn motor is only 10 degrees off-line. If i move one side and wait, move the other side and wait, then move middle, then reset…it may work, but you will be straining the motor against the stop of the steering arm (as it only rotates 25* each side off straight) and I’d rather not strain the motor for 2-3 seconds either side.
Again, you don’t need to strain the motor. Just set a low current limit and stop the motor as soon as the current limit kicks in. You’ll only be straining the motor for few milliseconds and it wouldn’t really be straining, given the current limit. My team used such a calibration strategy on their competition robots and it worked very well for them.
BTW: The gyro matching won’t work - the gyro sensors each have their own reference frame and know nothing about the other one. So if you start with the wheels turned full to one side, both gyros would happily report zero. Even if you calibrated the other way and reset the wheel gyro at the midpoint, both gyro sensors would drift over the time, each on its own pace and direction…
Nenik - Thank you so much for your assistance! - Yes, you’re right about the gyro’s (I haven’t used mine yet so they were all zero’d at the same angle, so it worked first time, but after I started resetting the gyro’s it got messed up) so onwards and upwards.
Onto your next proposal, it is sound, but for the life of me I cant figure out how to run an initialization loop that is inside the main ‘forever’ loop, that will not run the initialization part each time it loops. Here is my code so far. I am attempting to use the timers (which I guess start when the program starts) and I want the initialization to only run for the first 4 seconds, after that even with loop iterations it will skip that section and only run the ‘driving part’.
At the moment, the steering turns to the right, but then doesn’t do anything else…I cant figure out my error, (or another way of handling the initialization)
Oh, you don’t do that in the main loop (though your timer-based sequencing is quite creative - I’ve once had my students use something similar for sequencing actions while driving, but RobotC graphical missed variables back then)
You do the calibration first, then enter the main loop, pretty much like (simplified, w/o testing the current limiting):
setMotorCurrentLimit(steering, 200);
moveMotor(steering, 1, seconds, -50);
resetMotorEncoder(steering);
moveMotor(steering, 1, seconds, 50);
centre = getMotorEncoder(steering)/2;
setMotorTarget(steering, centre);
wait(1, seconds);
resetMotorEncoder(steering);
setMotorCurrentLimit(steering, 3000);
repeat(forever) {
// your driving code here
}
Your code didn’t work for few reasons:
[LIST=1]
The while() loop has the opposite condition (it would start calibrating after 4s)
moveMotor is a blocking function. It won't finish until the motor finishes the move, which it won't - it can't mechanically move one full rotation. That's why I use seconds instead.
you don't reset the encoder after reaching the midpoint.
[/LIST]
Hope this helps. You might need to tune the current limit, 200mA might be too low to steer on some surfaces.
As I wrote it, tankcontrol(ChA,ChA,10) will control the left and right wheels with one stick, making them both move as if they were on one axle. ChA is controlling both the left and right wheels. This will give you the desired effect.
Once again, Thank you so much for your advice! I may have to do this in RobotC non-graphical as I can’t figure out a way to setMotorCurrentLimit. I can read the current value from the motor and save the number in a variable, but the non-graphical way is much more elegant and straight forward.
I will play with different options and post the results once im done. - Ive also attached a arm and claw to the back of the ‘rover’ as this is one of the rovers I’m using for a space Winter camp that is up and coming. - the other rover, which is already built is a giant (but it was straight forward to program) - its a 6 wheeled articulated - 6 motor drive, two motors to lift a larger claw and a motor for the claw, so ive configured it with two brains (one kid will drive the wheels, the other kid will operate the arm and claw.) 6 wheels doesn’t work so well for turning, but that is kinda the point, the kids need to come up with pro’s and con’s for each design after they have all used each one in various challenges. (ill post pics)
Thank you, once again, for your generous assistance. It seems that I have hit the limit (excuse the pun) of what RobotC Graphical can do. I can’t see any blocks (even in Super User Mode) that can allow me to setMotorCurrentLimit - I can create a variable and READ the value that the motor is currently set to (about 3.5Amps! ) but I cant seem to set it?
Perhaps it’s time to switch over to regular RobotC?
AAhhh, Thank you Sankeydd, I miss read your previous post about TankControl. I didnt realise there were two ChA’s - Thanks ill give that a try as it’s simpler.