View unanswered posts | View active topics It is currently Mon Nov 24, 2014 10:02 am






Reply to topic  [ 4 posts ] 
Joystick control 
Author Message
Rookie

Joined: Mon Dec 09, 2013 2:08 pm
Posts: 8
Post Joystick control
Our team is attempting to write code for joystick control with our robot in RobotC for the FTC game. We are using Natural Language (TETRIX/MATRIX) for this. What we have now is working but not well, we believe it should be simpler than we are making it and we are looking for a few clues how to do this. Our current code for joystick control is attached. Thanks


Attachments:
SingleJoystickDrive.c [2.79 KiB]
Downloaded 156 times
Mon Dec 09, 2013 2:13 pm
Profile
Expert
User avatar

Joined: Sat Aug 31, 2013 9:15 am
Posts: 184
Post Re: Joystick control
First off, what exactly are you trying to do with this code? It seems like you are trying to create some sort of arcade-style drive. Is this correct?

In terms of code simplification, instead of using separate if statements for all of your different conditions, you could use if-else if-else statements. For example:
Code:
   if (x <= 90 && x >0 ){
      motorRightPower = (y * 100/128)/100 * (100 - (x * 100/90));
   }
   else if (x > 90){
      motorRightPower = (y * 100/128)/100 * -((x - 90) * 100/37); // Eliminated 0 - and changed it to simply -
   }
   else{
      motorRightPower = (y * 100/128); // Eliminated /100 * 100 because those two cancel out.
   }


Three of your conditions use exactly the same code, so this is just a way to make the code a little bit more efficient. I also adjusted your mathematical formulas a bit to make them more efficient. (See the comments above). Also, you need to change your integers to floats. Right now all of the math you are doing is integer math, so most of you division calculations will come out as 0. Simply change the parameters passed into the subroutine to:
Code:
int MCPRight(float x, float y)

_________________
FTC Team 6100 Chariots of Fire - Programmer (2012-2013)
FTC Team 7468 Blue Chariots of Fire - Programmer (2013-2014)
FTC Team 7468 Blue Chariots of Fire - Mentor (2014-2015)
Check out our team website at http://bluechariotsoffire.com/.


Mon Dec 09, 2013 2:49 pm
Profile
Guru
User avatar

Joined: Sun Nov 15, 2009 5:46 am
Posts: 1347
Post Re: Joystick control
Team6608 wrote:
Our team is attempting to write code for joystick control with our robot in RobotC for the FTC game. We are using Natural Language (TETRIX/MATRIX) for this. What we have now is working but not well, we believe it should be simpler than we are making it and we are looking for a few clues how to do this. Our current code for joystick control is attached. Thanks

Would you explain what you are trying to do because the code doesn't make sense? For example, just for this expression:
Code:
motorLeftPower = (y * 100/128)/100 * 100;

It looks like you are using integer arithmetic (i.e. motorLeftPower is an integer variable) which means you will always get a zero in the above expression. Let me explain: the expression y*100/128 is pretty much scaling the joystick range (-128 to 127) to the motor range (-100 to 100). Let's say y is 50, so the result will be 50*100/128 which is 39. Then you divide it with 100 and multiply with 100 which totally doesn't make sense. 39/100 in integer arithmetic will give you zero then multiply with 100 will again give you zero. So no matter what value y is (as long as it is within 128), you will always get a zero.

If you are doing arcade drive, it should be very simple:
Code:
#define DEADBAND(n,d)           ((abs(n) >= (d))? (n): 0)
#define JOYSTICK2MOTOR(n)       ((n)*100/128)
#define BOUND(n,low,high)            (((n) < (low))? (low): ((n) > (high))? (high): (n))

void ArcadeDrive(int x, int y)
{
    int leftMotorPower;
    int rightMotorPower;

    x = DEADBAND(x, 20);
    y = DEADBAND(y, 20);
    leftMotorPower = BOUND(JOYSTICK2MOTOR(y + x), -100, 100);
    rightMotorPower = BOUND(JOYSTICK2MOTOR(y - x), -100, 100);
    motor[leftMotor] = leftMotorPower;
    motor[rightMotor] = rightMotorPower;
}

task main()
{
    while (true)
    {
        getJoystickSettings(joystick);
        ArcadeDrive(joystick.joy1_x1, joystick.joy1_y1);
        wait1Msec(100);
    }
}

Notice I have defined three macros. It makes the code a lot easier to read. The first macro is DEADBAND. If you are not familiar with conditional expression, it is basically equivalent to:
Code:
int DeadBand(int n, int deadband)
{
    if (abs(n) >= deadband)
        return n;
    else
        return 0;
}

The second macro is JOYSTICK2MOTOR. It scales the joystick range (-128 to 127) to the motor power range (-100 to 100). It is pretty much self explanatory.

The third macro is to limit the power value to within the motor power range (-100 to 100). It is basically equivalent to:
Code:
int Bound(int n, int lowLimit, int highLimit)
{
    if (n < lowLimit)
        return lowLimit;
    else if (n > highLimit;
        return highLimit;
    else
        return n;
}

The first thing the DriveAcade function does is to apply DEADBAND to both the x and y joystick values. Then it calculates the left and right wheel power for arcade style driving. This means the left is adding x to y and the right is subtracting x from y. But by doing this your left and right motor power could exceed the 100 range again (e.g. if after scaling the joystick range to the motor range, both x and y are 100, you will get 200 for the left wheel). So you use the BOUND macro to limit the power back to the range of -100 to 100.
Now if you are picky about this clipping will limit your fine control on the driving, you could do more sophisticated algorithm to scale the motor power such that it gives you a wider range of control. But if your primary concern is to make arcade drive work, the above code should do it.


Mon Dec 09, 2013 4:23 pm
Profile
Guru
User avatar

Joined: Sun Nov 15, 2009 5:46 am
Posts: 1347
Post Re: Joystick control
Actually don't quite like my previous code. Alternatively, you can do this:
Code:
#define DEADBAND(n,d)           ((abs(n) >= (d))? (n): 0)
#define JOYSTICK2MOTOR(n)       ((n)*100/128)
#define BOUND(n,low,high)       (((n) < (low))? (low): ((n) > (high))? (high): (n))
#define JOYSTICK_POWER(n)       JOYSTICK2MOTOR(DEADBAND(n, 20))

void ArcadeDrive(int drivePower, int turnPower)
{
    //
    // Both drivePower and turnPower are in the range of -100 to 100.
    //
    motor[leftMotor] = BOUND(drivePower + turnPower, -100, 100);
    motor[rightMotor] = BOUND(drivePower - turnPower, -100, 100);
}

task main()
{
    while (true)
    {
        getJoystickSettings(joystick);
        //
        // Scale the joystick x and y to the motor power range (-100 to 100) after applying deadband.
        //
        ArcadeDrive(JOYSTICK_POWER(joystick.joy1_x1), JOYSTICK_POWER(joystick.joy1_y1));
        wait1Msec(100);
    }
}


Mon Dec 09, 2013 4:41 pm
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 4 posts ] 

Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  



Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.