Okay, so I’ve been working on testing my code on a practice bot and need help. I’m using an Attack 3 Joystick (I have 2 ) and a robot with 4 mecanum wheels, each with 4 victors.
Problem is: I have the sample code for a 2 motor robot and am having trouble creating a 4 motor drivetrain and using mecanum wheels.
I create the drive system by doing this:
RobotDrive *myRobot;
Joystick stick;
then
myRobot = new Robotdrive(1,2,3,4);
stick = new Joystick(1);
Except this isn’t working. Do I need to declare something specific for the victors or logitech attack 3 joystick? And am I assigning the one joystick to control the whole robotdrive? I really need some help, anything would be appreciated at this point.
Joystick stick should be declared as a pointer, like so:
Joystick *stick;
The Attack3 joysticks do not have a 3rd(Twist) axis. In order to properly handle this, you could use a different joystick with a 3rd axis, use an axis(x or y) from a 2nd joystick, or wire up your own potentiometer or other device to read rotation.
By default, the RobotDrive class will instantiate Jaguars as its motor controllers. If you are using Victors you need to explicitly instantiating them yourself and use the following constructor instead:
class MyRobot: public SimpleRobot
{
Victor leftFrontMotor;
Victor leftRearMotor;
Victor rightFrontMotor;
Victor rightRearMotor;
RobotDrive drive;
MyRobot():
leftFrontMotor(1),
leftRearMotor(2),
rightFrontMotor(3),
rightRearMotor(4),
drive(&leftFrontMotor, &leftRearMotor, &rightFrontMotor, &rightRearMotor)
{
}
....
}
Okay so here is where I stand, don’t have a chance to test it on the practice bot today but will tomorrow. Anyone got any advice on the program and is there anything essential I should add or do to this program? Not totally sure how to do the twist part for the Mecanum wheels using an Attack3 joystick…
Here it is:
#include "WPILib.h"
class RobotDemo : public SimpleRobot
{
RobotDrive *drive;
Victor *leftFrontMotor;
Victor *leftRearMotor;
Victor *rightFrontMotor;
Victor *rightRearMotor;
Joystick *Attack1;
Joystick *Attack2;
public:
RobotDemo(void)
{
drive = new RobotDrive(leftFrontMotor,leftRearMotor,rightFrontMotor,rightRearMotor);
Attack1 = new Joystick(1);
Attack2 = new Joystick(2);
GetWatchdog().SetExpiration(0.1);
drive->SetExpiration(0.1);
}
void Autonomous(void)
{
}
void OperatorControl(void)
{
GetWatchdog().SetEnabled(true);
drive->SetSafetyEnabled(true);
while (IsOperatorControl())
{
drive->MecanumDrive_Cartesian(Attack1->GetX(),Attack1->GetY(),Attack2->GetTwist());
Wait(0.005);
}
}
};
START_ROBOT_CLASS(RobotDemo);
No, your code just declared four Victor pointers but you did not instantiate them. Regarding the Attack3 joystick, can’t help you on that since I am not familiar with it.
#include "WPILib.h"
class RobotDemo : public SimpleRobot
{
Victor *leftFrontMotor;
Victor *leftRearMotor;
Victor *rightFrontMotor;
Victor *rightRearMotor;
RobotDrive *drive;
Joystick *Attack1;
Joystick *Attack2;
public:
RobotDemo(void)
{
leftFrontMotor = new Victor(1);
leftRearMotor = new Victor(2);
rightFrontMotor = new Victor(3);
rightRearMotor = new Victor(4);
drive = new RobotDrive(leftFrontMotor,leftRearMotor,rightFrontMotor,rightRearMotor);
Attack1 = new Joystick(1);
Attack2 = new Joystick(2);
GetWatchdog().SetExpiration(0.1);
drive->SetExpiration(0.1);
}
void Autonomous(void)
{
}
void OperatorControl(void)
{
GetWatchdog().SetEnabled(true);
drive->SetSafetyEnabled(true);
while (IsOperatorControl())
{
drive->MecanumDrive_Cartesian(Attack1->GetX(),Attack1->GetY(),Attack2->GetTwist());
Wait(0.005);
}
}
};
START_ROBOT_CLASS(RobotDemo);
Oh wait my bad - forgot to do that…thank you. And do you know if I should program anything to handle switching between operator control and autonomous - or will this program automatically handle that during competition?
I am not sure if I understand your question. The Field Management System will dictate what mode (autonomous or teleop) the robot is in and will call either Autonomous or OperatorControl methods of your robot code. So you don’t need to write any code to “switch mode”. However, you do need to write code for both the Autonomous and OperatorControl functions.
Ah, was just wondering how each part of the game is handled. And last question (I promise!) - if I have lets say a jaguar powering a belt that moves the ball, how could I go about programming that? I’m lost on how to control motors that does not involve the wheels.
How do you control the Jaguar? By PWM or by CAN bus. Let me assume you are using PWM. Then it would look something like this:
Jaguar *beltMotor;
...
beltMotor = new Jaguar(1); //assuming PWM channel 1
...
beltMotor->Set(1.0); //turning one way full speed
beltMotor->Set(-1.0); //turning the other way full speed
beltMotor->Set(0.0); //stop
You require the second joystick because each Attack3 only has 2 axes, but you need 3. So you will use the X- and Y-axis of Attack1 for moving straight(front/back and sideways), and the X-axis of Attack2 to do rotation. the getTwist method does nothing with Attack3 joysticks because they don’t have the 3rd(or Twist) axis.
Alright, thank you! However, I was sure everything was ready to go but now im getting a watchdog not fed error. I feed the watchdog but its not working. Does anyone know how to fix this?
#include "WPILib.h"
class RobotDemo : public SimpleRobot
{
Victor *leftFrontMotor;
Victor *leftRearMotor;
Victor *rightFrontMotor;
Victor *rightRearMotor;
RobotDrive *drive; // Drive system for the robot
Joystick *Attack1; // Plugged into USB port 1
Joystick *Attack2; // Plugged into USB port 2
Jaguar *beltMotor; // Slides the cart for the basketballs
Jaguar *angleMotor; // Changes the angle for the basketball shooter
Jaguar *bshooter; // Moves the belt to shoot the basketball (Must be able to go forward and backward)
public:
RobotDemo(void)
{
//Initialize the four Victors to power the Mecanum wheels
leftFrontMotor = new Victor(1);
leftRearMotor = new Victor(2);
rightFrontMotor = new Victor(3);
rightRearMotor = new Victor(4);
//Initialize the drive system
drive = new RobotDrive(leftFrontMotor,leftRearMotor,rightFrontMotor,rightRearMotor);
//Initialize the two joysticks used to control the robot
//Define joysticks being used at USB port #1 and USB port #2 on the Driver's Station
Attack1 = new Joystick(1);
Attack2 = new Joystick(2);
//Initialize Jaguars for the various Robot's functions
beltMotor = new Jaguar(5);
angleMotor = new Jaguar(6);
bshooter = new Jaguar(7);
Watchdog().SetExpiration(0.1);
drive->SetExpiration(0.1);
drive->SetSafetyEnabled(false);
printf("Object Initialization is a success!");
}
void Autonomous(void)
{
while (IsAutonomous() && IsEnabled()) {
Watchdog().SetEnabled(false);
}
}
void OperatorControl(void)
{
//Enable Watchdog which is responsible for handling robot failure
Watchdog().SetEnabled(true);
drive->SetSafetyEnabled(true);
//Enter the loop where robot can be controlled manually
while (IsOperatorControl())
{
Watchdog().Feed();
printf("The Operator Controlled period has begun!");
//Use Attack3 joysticks to drive the robot
drive->MecanumDrive_Cartesian(Attack1->GetX(),Attack1->GetY(),Attack2->GetX());
Wait(0.001);
}
}
};
START_ROBOT_CLASS(RobotDemo);