Chief Delphi

Chief Delphi (http://www.chiefdelphi.com/forums/index.php)
-   Programming (http://www.chiefdelphi.com/forums/forumdisplay.php?f=51)
-   -   switching turning direction using arcade drive? (http://www.chiefdelphi.com/forums/showthread.php?t=84177)

Kyledoo 11-03-2010 23:26

switching turning direction using arcade drive?
 
We have implemented a way to change the polarity of the motors by hitting a button(simply using the SetInvertedMotor), and in this way, we can select which end of our robot is the front. However, while in the reversed mode, pushing the stick to the left turns the robot to the right. I was exploring a way to basically invert the x axis of the joystick. any ideas on how to do this? oh and we have our first matches tomorrow, so i'm hoping to figure it out sooner rather than later!
We are using C++

apalrd 11-03-2010 23:32

Re: switching turning direction using arcade drive?
 
if(inverted)
{
xOut = x * -1;
}

Couldn't be more simple than that.

Tom Bottiglieri 11-03-2010 23:35

Re: switching turning direction using arcade drive?
 
You can use the ArcadeDrive method that takes raw values for the speed/turn inputs. This is the signature:
Code:

void RobotDrive::ArcadeDrive(float moveValue, float rotateValue, bool squaredInputs = true);
So instead of doing something like this
Code:

myDrive.ArcadeDrive(myJoystick);
You could do something like
Code:

float orientation = 1;

if(goingBackwards)
  orientation = -1;

myDrive.ArcadeDrive(myJoystick.GetY() * orientation, myJoystick.GetX());

You shouldn't have to reverse the motors with that.

EDIT: You shouldn't have to reverse the X axis actually. Kind of counter intuitive, but thats the way it works out. A left hand turn is a left hand turn looking forward and backward. You just want to change your direction. (moveValue)

Kyledoo 12-03-2010 00:05

Re: switching turning direction using arcade drive?
 
Thanks for the great quick responses! I really can't believe i missed that now... but anyways, is anyone timing the release of pnumatics(we want to leave our kicker extended for a full second once we press the button). What makes most sense to me is to use a for loop, and possibly put this inside an if.
For example:
if(buttonpressed){
for(i = 0; i<10; i++){
// whole code
//feed watchdog
s1->Set(true);
Wait(.1);
}
}
any experiences with this? we basically have tomorrow morning to test all the code and make any necessary modifications so i'd just like to know what to expect. Also, would this concept work for restricting kicker movement after it retracts(so we don't get a penalty)?

Tom Bottiglieri 12-03-2010 02:26

Re: switching turning direction using arcade drive?
 
You probably dont want to have any kind of nested loops in your main program loop, unless you are certain it will execute fast enough. A for loop will block the execution of the code after it, and will fire the watch dog, or worse, cause your bot to "freeze" its output values while the loop is executing.

Instead, you could use a Timer object.
Code:

class MyRobot : public IterativeRobot
{
  // Declare the timer
  Timer * kickTimer;
 
  // Then down in the constructor...
  MyRobot(void){
      // ...
      kickTimer = new Timer();
  }

  void TeleopPeriodic(void){
      if( somethingHappened ){
        kickTimer->Start();
        mySolenoid->Set(true);
      }

      if( kickTimer->Get() >= 1.0){
        mySolenoid->Set(false);
        kickTimer->Stop();
        kickTimer->Reset();
      }
}

Or you could just increment a counter every time you loop around
Code:

static unsigned int solenoidCounts = 0;
static bool kickerFired = false;

if(somethingHappened){
  solenoid->Set(true);
  kickerFired = true;
  solenoidCounts = 0;
}

if(kickerFired){
  solenoidCounts++;
  if(solenoidCounts > 1 * 40){ // 40Hz(ish)
      solenoid->Set(false);
      kickerFired = false;
      solenoidCounts = 0; // just to be safe
  }
}

It's not the prettiest thing in the world, but it gets the job done and its pretty easy to understand/implement/change.

Kyledoo 25-03-2010 23:17

Re: switching turning direction using arcade drive?
 
Quote:

Originally Posted by Tom Bottiglieri (Post 935877)
You probably dont want to have any kind of nested loops in your main program loop, unless you are certain it will execute fast enough. A for loop will block the execution of the code after it, and will fire the watch dog, or worse, cause your bot to "freeze" its output values while the loop is executing.

Instead, you could use a Timer object.
Code:

class MyRobot : public IterativeRobot
{
  // Declare the timer
  Timer * kickTimer;
 
  // Then down in the constructor...
  MyRobot(void){
      // ...
      kickTimer = new Timer();
  }

  void TeleopPeriodic(void){
      if( somethingHappened ){
        kickTimer->Start();
        mySolenoid->Set(true);
      }

      if( kickTimer->Get() >= 1.0){
        mySolenoid->Set(false);
        kickTimer->Stop();
        kickTimer->Reset();
      }
}

Or you could just increment a counter every time you loop around
Code:

static unsigned int solenoidCounts = 0;
static bool kickerFired = false;

if(somethingHappened){
  solenoid->Set(true);
  kickerFired = true;
  solenoidCounts = 0;
}

if(kickerFired){
  solenoidCounts++;
  if(solenoidCounts > 1 * 40){ // 40Hz(ish)
      solenoid->Set(false);
      kickerFired = false;
      solenoidCounts = 0; // just to be safe
  }
}

It's not the prettiest thing in the world, but it gets the job done and its pretty easy to understand/implement/change.

Hey. I know it has been awhile since I actually asked this question, but we are now at our second regional(Buckeye) and it has been quite hectic. I just wanted to thank you for all the advice, I used that same format you suggested and we were even able to put in a penalty preventer so that the kicker will not fire more than once every 2 seconds.


All times are GMT -5. The time now is 03:26.

Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi