Hey guys! I know it’s kinda early in the season for code issues, but I’ve got a question about toggle code. How come this:
bool Toggle, Button2Value;
Button2Value = false;
Toggle = false;
if(stick1.GetRawButton(2))
{
if(Button2Value == false)
{
Button2Value = true;
Toggle = !Toggle;
}
}
else
{
Button2Value = false;
}
would not change the value of Toggle afterwards? the idea is that button 2 can be pressed for an unlimited amount of time, then let go and the value of Toggle would be switched, until it was pressed again for an undefined amount of time. However, whenever I run it the Toggle variable never seems to change value. If the rest of the code is required, just ask and I’ll post it.
Where is the loop for this program? Is everything that you posted inside of the same loop? If so, it seems that you are redeclaring and reinitializing your variables at every cycle, which is generally not good.
It would help to see the code. This looks like it should kinda work. You are setting the variable you intend to toggle to zero each time through this code, hopefully it doesn’t really work that way. And if you are not using the Toggle variable anywhere the compiler may have optimized (deduced that the value of Toggle does not really matter) the whole thing away.
HTH
Button2Value = false;
Toggle = false;
if(stick1.GetRawButton(2))
{
if(Button2Value == false)
{
Button2Value = true;
Toggle = !Toggle;
}
}
else
{
Button2Value = false;
}
The rest of the code may be important. For instance if this is called in a function the toggle value will be reset every time the function is called. Are you sure the same Toggle is in scope when you check? If either of these is the case put the declaration and initialization of Toggle at a level where is is seen and changed appropriately (class level as public member perhaps).
When button 2 is pressed Toggle will change immediately. When the button is released it will only change the Button2Value on the next call, not right away. Are you sure the calling code allows for that? For instance if you check button 2 is true before calling this code Button2Value would never reset.
There is also a chance that ‘bounce’ is your problem. Where the button connection is bouncing between true and false at the moment contact is just being made or broken. See http://en.wikipedia.org/wiki/Switch ‘contact bounce’. There are a couple of ways to handle that, usually a timer that enforces a minimum time between state changes. A tenth of a second is probably more than sufficient.
Shoot!!! yup…the initialization should be outside of the while loop. We don’t work on tuesdays so I’ll test it tomorrow, but ya’ll think this should work?
#include "WPILib.h"
class RobotDemo : public SimpleRobot
{
RobotDrive myRobot; // robot drive system
Joystick stick1; // only joystick
Victor Left1, Left2, Right1, Right2; // drive motors
public:
RobotDemo():
myRobot(1, 2), // these must be initialized in the same order
stick1(1), // as they are declared above.
Left1(9),
Left2(7),
Right1(8),
Right2(6)
{
myRobot.SetExpiration(0.1);
}
/**
* Drive left & right motors for 2 seconds then stop
*/
void Autonomous()
{
myRobot.SetSafetyEnabled(false);
myRobot.Drive(-0.5, 0.0); // drive forwards half speed
Wait(2.0); // for 2 seconds
myRobot.Drive(0.0, 0.0); // stop robot
}
void OperatorControl()
{
myRobot.SetSafetyEnabled(true);
bool BackwardToggle, Button2Value;
float Xaxis, Yaxis, LeftDrive, RightDrive, NecessaryTest;
BackwardToggle = false;
Button2Value = false;
while (IsOperatorControl())
{
if(stick1.GetRawButton(2))
{
if(Button2Value == false)
{
Button2Value = true;
BackwardToggle = !BackwardToggle;
}
}
else
{
Button2Value = false;
}
Yaxis = stick1.GetRawAxis(2);
Xaxis = stick1.GetRawAxis(1); // x is 1, y is 2
RightDrive = Xaxis + Yaxis;
LeftDrive = Xaxis - Yaxis;
NecessaryTest = LeftDrive - RightDrive;
if(NecessaryTest < 0.1 && NecessaryTest > -0.1)
{
NecessaryTest = (LeftDrive+RightDrive)/2;
LeftDrive = NecessaryTest;
RightDrive = NecessaryTest;
}
if(stick1.GetTrigger())
{
if(stick1.GetRawButton(2) == false)
{
Left1.Set(LeftDrive);
Left2.Set(LeftDrive);
Right1.Set(RightDrive);
Right2.Set(RightDrive);
}
else if(stick1.GetRawButton(2) == true)
{
Left1.Set(RightDrive);
Left2.Set(RightDrive);
Right1.Set(LeftDrive);
Right2.Set(LeftDrive);
}
}
else
{
Left1.Set(0.0);
Left2.Set(0.0);
Right1.Set(0.0);
Right2.Set(0.0);
}
Wait(0.005); // wait for a motor update time
}
}
/**
* Runs during test mode
*/
void Test() {
}
};
START_ROBOT_CLASS(RobotDemo);
One subtlety of programming that new programmers often miss out on is correctly naming variables.
In your program, I’d consider renaming Button2Value to Button2WasPressed, BackwardToggle to DriveBackwards, NecessaryTest to something like SpeedDifference, and LeftDrive/RightDrive to LeftPower/RightPower. You can easily do so by right clicking on the variable, and selecting Refactor -> Rename.
Making those changes makes your program easier to comprehend.
Down in the if (stick1.getTrigger()) blocks are you intending to change those to use BackwardToggle?
You don’t need to say
else if(stick1.GetRawButton(2) == true)
because it’s the opposite of the first test for false – you can just say “else”.
Is it your intent for driving to work only when the trigger is pulled?
yeah, it’s designed to only be driven with the trigger just so that people cant accidentally knock the joystick and have the robot move.
and yeah my mentor didn’t want to be able to switch it into reverse unless the trigger was not being pressed, that way the driver couldn’t damage the motors.