View Single Post
  #4   Spotlight this post!  
Unread 17-12-2013, 03:05
mikets's Avatar
mikets mikets is offline
Software Engineer
FRC #0492 (Titan Robotics)
Team Role: Mentor
 
Join Date: Jan 2010
Rookie Year: 2008
Location: Bellevue, WA
Posts: 667
mikets is a glorious beacon of lightmikets is a glorious beacon of lightmikets is a glorious beacon of lightmikets is a glorious beacon of lightmikets is a glorious beacon of lightmikets is a glorious beacon of light
Re: C++ Toggle Button

This is one of the programming topics I teach my students: how to make something happen when a button is pressed or released. The first challenge is to detect button presses and releases as an edge event. The second challenge is to toggle a mode when a button is pressed. For the first challenge, detecting an edge event means to detect the transition between two states which means you need to remember the previous state and compare it with the current state. This could be done with two Boolean variables.
Code:
bool prevState = false;
bool currState = false;

while (IsOperatorControl())
{
    //
    // Check for button 6 press.
    //
    currState = secondaryController->GetRawButton(6);
    if (currState != prevState)
    {
        if (currState)
        {
            //
            // Button has been pressed.
            //
        }
        else
        {
            //
            // Button has been released.
            //
        }
        prevState = currState;
    }

    wait(0.02);
}
For the second challenge, you simply toggle a Boolean variable like this:
Code:
bool driveTankMode = false;

driveTankMode = !driveTankMode;
So put them all together:
Code:
bool prevState = false;
bool currState = false;
bool driveTankMode = false;

while (IsOperatorControl())
{
    //
    // Check for button 6 press.
    //
    currState = secondaryController->GetRawButton(6);
    if (currState != prevState)
    {
        if (currState)
        {
            //
            // Button has been pressed.
            //
            driveTankMode = !driveTankMode;
        }
        else
        {
            //
            // Button has been released.
            //
        }
        prevState = currState;
    }

    if (driveTankMode)
    {
        //
        // Do tank drive.
        //
   }
    else
    {
        //
        // Do arcade drive.
        //
   }

    wait(0.02);
}
You can use the edge event detection code to not only toggle a mode, you can do different things when a button is pressed and released. For example, some teams like to "slow down the robot when driving with a button pressed and held down". So you could have the "pressed event" to set the joystick divisor to 2.0 and the "released event" to set the divisor back to 1.0.
Our team even went further to define a joystick button class where the code will be called periodically to check for all button changes. When any button has changed state, it will do an event callback with the parameters specifying which joystick, which button and whether it was a pressed or released event. This greatly simplify our code. For example, our joystick class is TrcJoystick.
Code:
class MyRobot
    : public SimpleRobot
    , public ButtonNotify
{
private:
    TrcJoystick m_leftDriveStick;
    TrcJoystick m_rightDriveStick;

public:
    MyRobot(void)
        : m_leftDriveStick(1, this)    //joystick 1, call this class for button events
        , m_rightDriveStick(2, this)   //joystick 2, call this class for button events
    {
    }

    void NotifyButton(
        UINT32 joystickNum,
        UINT16 bitButton,
        bool   fPressed
        )
    {
        if (joystickNum == 1)
        {
            switch (bitButton)
            {
                case Logitech_Trigger:
                    break;

                case Logitech_Btn2:
                    break;
            }
        }
        else if (joystickNum == 2)
        {
            switch (bitButton)
            {
                 case Logitech_Trigger:
                    break;

                case Logitech_Btn2:
                    break;
            }
        }
        else if (joystickNum == 3)
        {
            switch (bitButton)
            {
                 case Logitech_Trigger:
                    break;

                case Logitech_Btn2:
                    break;
            }
        }
    }
};
__________________
Reply With Quote