Help with custom drive code

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.

Do the motor values allow equations to use decimals? I wasn’t sure about it for RobotC, since I’ve never seen anyone try it that way before. :confused:

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.

Jpearman goes more in depth about why its allowed above.

PID loops for example do the same sort of multiplication so it is commonly used just a little harder to see.

motor=kperror
is really saying
set motor to .6
104 and robotC makes that 60 power
or set motor to .6*1000 and robotC cleans that up to be 127 power

Hope this isn’t a dumb question. How does one view the “machine language”. I didn’t know this option existed.

Using the menu “View->Assembly” (after a compile) also F9 does this. You need to enable “super user” level of menus (under window->menu level)

Thank you very much.

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.