I am working in RobotC. I currently have a simple drive code for the user control portion of the match. I would like to make it so I drive forward at full speed, but my turning speed is reduced. It this means I would lose my tank drive control that is fine. Can anyone help me out?
This is my current code:
//Wheel Drive at 60% for Right, and 61% for Left
motor[frontRight] = vexRT[Ch2]*.60;
motor[backRight] = vexRT[Ch2]*.60;
motor[frontLeft] = vexRT[Ch3]*.61;
motor[backLeft] = vexRT[Ch3]*.61;
In RobotC, I think the values sent to the motors must be integers and not floats. In other words, you should not use decimals in the math. Instead, you might do something like this:
motor[frontRight] = (vexRT[Ch2]*60)/100;
Be aware that when you do any integer math, your results get truncated. So, in other words, if you have a math equation with something like
MotorValue = 5/2;
MotorValue ends up with a value of 2, and not 2.5. And that’s because the integer math drops the decimal portion. Integer math can not “see” decimals.
Your turn speed should be able to be controlled by how far you swing the joysticks with your current code. That’s the good thing about using joysticks to obtain motor values. You should have “infinite” control over how fast you turn by regulating the motion of your thumbs.
Also, your current code never allows you to go full speed, even in the forward direction. Full speed forward is +127, but you are multipying that by .6 giving the value of 76.2. Also, not quite sure why you have one side mulitplied by .6 and the other .61. I’m going to assume that you had some drifting problems? However, a .01 difference is unlikely to have corrected anything.
127 x .60 = 76.2
127 x .61 = 77.6
This is most likely to small of a change to have any actual affect on the robot.
If you desire to have automated turning at half speed then you will most likely have to incorporate the use of arcade mode driving instead of tank control. This would allow you to manipulate your forward/reverse speed independently of your turning speed. With tank style driving the two directions of motion are inherently connected.
I’m actually not sure, I was just trying to show the OP that the difference is so small between .6 and .61 that it would essentially be irrelevant. I am a relative RobotC newby, so I would trust that you are correct about the decimal values not being the correct way to do it.
The method you showed to do x60/100 is a sure fire way to be correct.
One of the (many) great features of ROBOTC is that it allows you to see the “machine language” instructions that it generates from the C code, lets take a look at an example. I created this small program that follows the structure that the OP used.
task main()
{
while(1)
{
//Wheel Drive at 60% for Right, and 61% for Left
motor[port2] = vexRT[Ch2]*.60;
motor[port3] = vexRT[Ch2]*.60;
motor[port4] = vexRT[Ch3]*.61;
motor[port5] = vexRT[Ch3]*.61;
}
}
This is the assembly language output.
//Code segment: main(); Task: 0
//
0000: 170000 callSub(_procedureForMotorsAndSensorsSetup_, 0)
{
while(1)
{
//Wheel Drive at 60% for Right, and 61% for Left
motor[port2] = vexRT[Ch2]*.60;
0003: 4D4529000001 L0003: S00(short) = (short) GetProperty(propertyIFIRadioControl, Ch2:1)
0009: AC2D0400290000 S04(float) = S00(short) // Store in temp variable :: Convert 'signed short' to 'float'
0010: 922D04009A99193F S04(float) *= 0.6 // Perform <op> on temp variable :: float
0018: AE2904002D0400 S04(short) = S04(float) // Convert 'float' to 'short'
001F: 570A29040001 SetProperty(propertyMotorPower, port2:1, S04(short))
motor[port3] = vexRT[Ch2]*.60;
0025: 4D4529000001 S00(short) = (short) GetProperty(propertyIFIRadioControl, Ch2:1)
002B: AC2D0400290000 S04(float) = S00(short) // Store in temp variable :: Convert 'signed short' to 'float'
0032: 922D04009A99193F S04(float) *= 0.6 // Perform <op> on temp variable :: float
003A: AE2904002D0400 S04(short) = S04(float) // Convert 'float' to 'short'
0041: 570A29040002 SetProperty(propertyMotorPower, port3:2, S04(short))
motor[port4] = vexRT[Ch3]*.61;
0047: 4D4529000002 S00(short) = (short) GetProperty(propertyIFIRadioControl, Ch3:2)
004D: AC2D0400290000 S04(float) = S00(short) // Store in temp variable :: Convert 'signed short' to 'float'
0054: 922D0400F6281C3F S04(float) *= 0.61 // Perform <op> on temp variable :: float
005C: AE2904002D0400 S04(short) = S04(float) // Convert 'float' to 'short'
0063: 570A29040003 SetProperty(propertyMotorPower, port4:3, S04(short))
motor[port5] = vexRT[Ch3]*.61;
0069: 4D4529000002 S00(short) = (short) GetProperty(propertyIFIRadioControl, Ch3:2)
006F: AC2D0400290000 S04(float) = S00(short) // Store in temp variable :: Convert 'signed short' to 'float'
0076: 922D0400F6281C3F S04(float) *= 0.61 // Perform <op> on temp variable :: float
007E: AE2904002D0400 S04(short) = S04(float) // Convert 'float' to 'short'
0085: 570A29040004 SetProperty(propertyMotorPower, port5:4, S04(short))
}
008B: 7877FF BranchFar(L0003) // Jump to end Expression
0000: 7B Return() // _main__()
So the motor assignment statement has been converted in this way (pseudo code)
store the joystick value in a short variable
convert that value to a floating point variable
multiply the float value by 0.6 (or 0.61)
convert the answer back to a short variable
send the final answer to the motor
So don’t worry about using floating point math, the ROBOTC compiler takes care of the conversions for you.
Thanks for all the feedback guys. Assuming I did migrate it to an arcade drive and removed my speed reduction (multiplying by .6 & .61) how would I go about coding to make my motors move at full speed for forward and backwards, and say half speed for left and right turns?
I’m still confused as to why you want to have “half speed for turns”. You can control the speed by how far you turn the stick, correct? When you completely limit your robot from reaching full speed that may come back to bite you because there may be a time that you want full power in a turn. (turning into a pile of cubes or pushing another robot for example) It is generally a bad idea to completely limit the capacity of your motors through your code.
Again, you can already go half speed by moving the stick half of the distance of full travel, so why limit yourself completely through the code?
Nonetheless, I will try to get back to you shortly as to how you COULD do what you are asking…just busy at the moment…
If you define “turn” as “x_joystick away from zero center position”,
then you can use that definition to scale the motor speed.
Try scaling the motor speeds by a scalefactor of 100% down to 50% as a function of abs(x_joystick) goes from 0 to 127; untested pseudo code follows:
minspd = 0.5; // constant: min scaling factor, never less than this
otrspd = 1 - minspd; // constant: min+otr add up to 1 = 100%
jx = get joystick_x; // -127 to 000 to +127
ajx = abs(jx); // +127 to 000 to +127
ajxi = 127 - ajx; // 000 to 127 to 000
ajxis = ajxi/127; // 0.0 to 1.0 to 0.0
scalefactor = minspd + otrspd*ajxis; // 0.5 to 1.0 to 0.5
//or all in one swell foop with 0.50 as 'say half'
scalefactor = 0.50 + (1-0.50)*(127-abs(x_joystick))/127;
You should post your own arcade code for people to help you better.