ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Here is my implementing of teleop for carlike robot. Instead of Twist (whish has 6 variables) I use simple Drive message containing only acceleration and steering angle. Hope it would be helpful somehow.

    #include "ros/ros.h"
#include "drive_base/Drive.h"
#include "sstream"
#include <termios.h>
#include <signal.h>
#include <fcntl.h>


  #define KEYCODE_A 0x61
  #define KEYCODE_D 0x64
  #define KEYCODE_S 0x73
  #define KEYCODE_W 0x77

  class TeleopRoboCVKeyboard
  {
    private:
    drive_base::Drive cmd;

    ros::NodeHandle n_;
    ros::Publisher drive_pub_;

    public:
    void init()
    {


      //Clear out our cmd - these values are roundabout initials

      cmd.Acceleration = 0;
      cmd.Angle = 0;

      drive_pub_ = n_.advertise<drive_base::Drive>("command", 100);

      ros::NodeHandle n_private("~");
    }

    ~TeleopRoboCVKeyboard()   { }
    void keyboardLoop();
  };

  int kfd = 0;
  struct termios cooked, raw;

  void quit(int sig)
  {
    tcsetattr(kfd, TCSANOW, &cooked);
   exit(0);
  }

  int main(int argc, char** argv)
  {
    ros::init(argc, argv, "drive_cmd_publisher");

    TeleopRoboCVKeyboard tpk;
    tpk.init();

    signal(SIGINT,quit);

    tpk.keyboardLoop();

    return(0);
  }

  void TeleopRoboCVKeyboard::keyboardLoop()
  {
    char c;
   bool dirty=false;

    // get the console in raw mode
    tcgetattr(kfd, &cooked);
    memcpy(&raw, &cooked, sizeof(struct termios));
    raw.c_lflag &=~ (ICANON | ECHO);
    // Setting a new line, then end of file
    raw.c_cc[VEOL] = 1;
    raw.c_cc[VEOF] = 2;
    tcsetattr(kfd, TCSANOW, &raw);

    puts("Reading from keyboard");
    puts("---------------------------");
    puts("Use 'WS' to forward/back");
    puts("Use 'AD' to left/right");

    for(;;)
    {
      // get the next event from the keyboard
      if(read(kfd, &c, 1) < 0)
      {
        perror("read():");
        exit(-1);
      }

      switch(c)
      {
        // Walking
      case KEYCODE_W:
    puts("throttle");
        cmd.Acceleration = cmd.Acceleration + 10;
        dirty = true;
        break;
      case KEYCODE_S:
    puts("brake");
        cmd.Acceleration = cmd.Acceleration - 10;
        dirty = true;
        break;
      case KEYCODE_A:
    puts("turn left");
        cmd.Angle = cmd.Angle - 0.1;
        dirty = true;
        break;
      case KEYCODE_D:
    puts("turn right");
        cmd.Angle = cmd.Angle + 0.1;
        dirty = true;
        break; 
      }


      if (dirty == true)
      {
        drive_pub_.publish(cmd);
      }


    }
  }

Here is my implementing implementation of teleop for carlike robot. Instead of Twist (whish has 6 variables) I use simple Drive message containing only acceleration and steering angle. Hope it would be helpful somehow.

    #include "ros/ros.h"
#include "drive_base/Drive.h"
#include "sstream"
#include <termios.h>
#include <signal.h>
#include <fcntl.h>


  #define KEYCODE_A 0x61
  #define KEYCODE_D 0x64
  #define KEYCODE_S 0x73
  #define KEYCODE_W 0x77

  class TeleopRoboCVKeyboard
  {
    private:
    drive_base::Drive cmd;

    ros::NodeHandle n_;
    ros::Publisher drive_pub_;

    public:
    void init()
    {


      //Clear out our cmd - these values are roundabout initials

      cmd.Acceleration = 0;
      cmd.Angle = 0;

      drive_pub_ = n_.advertise<drive_base::Drive>("command", 100);

      ros::NodeHandle n_private("~");
    }

    ~TeleopRoboCVKeyboard()   { }
    void keyboardLoop();
  };

  int kfd = 0;
  struct termios cooked, raw;

  void quit(int sig)
  {
    tcsetattr(kfd, TCSANOW, &cooked);
   exit(0);
  }

  int main(int argc, char** argv)
  {
    ros::init(argc, argv, "drive_cmd_publisher");

    TeleopRoboCVKeyboard tpk;
    tpk.init();

    signal(SIGINT,quit);

    tpk.keyboardLoop();

    return(0);
  }

  void TeleopRoboCVKeyboard::keyboardLoop()
  {
    char c;
   bool dirty=false;

    // get the console in raw mode
    tcgetattr(kfd, &cooked);
    memcpy(&raw, &cooked, sizeof(struct termios));
    raw.c_lflag &=~ (ICANON | ECHO);
    // Setting a new line, then end of file
    raw.c_cc[VEOL] = 1;
    raw.c_cc[VEOF] = 2;
    tcsetattr(kfd, TCSANOW, &raw);

    puts("Reading from keyboard");
    puts("---------------------------");
    puts("Use 'WS' to forward/back");
    puts("Use 'AD' to left/right");

    for(;;)
    {
      // get the next event from the keyboard
      if(read(kfd, &c, 1) < 0)
      {
        perror("read():");
        exit(-1);
      }

      switch(c)
      {
        // Walking
      case KEYCODE_W:
    puts("throttle");
        cmd.Acceleration = cmd.Acceleration + 10;
        dirty = true;
        break;
      case KEYCODE_S:
    puts("brake");
        cmd.Acceleration = cmd.Acceleration - 10;
        dirty = true;
        break;
      case KEYCODE_A:
    puts("turn left");
        cmd.Angle = cmd.Angle - 0.1;
        dirty = true;
        break;
      case KEYCODE_D:
    puts("turn right");
        cmd.Angle = cmd.Angle + 0.1;
        dirty = true;
        break; 
      }


      if (dirty == true)
      {
        drive_pub_.publish(cmd);
      }


    }
  }