Project

General

Profile

Revision 08be08ec

ID08be08eccb9e416e087e702d6562cb9452a64629
Parent 759284c0
Child f0c4b45e

Added by Tahm over 10 years ago

Ran astyle, though astyle options still need to be refined

View differences:

buggysim/include/buggysim/buggy.h
54 54
namespace buggysim
55 55
{
56 56

  
57
class Turtle
58
{
59
public:
60
  Turtle(const ros::NodeHandle& nh, 
61
	 const QImage& turtle_image, 
62
	 const QPointF& pos, 
63
	 float orient);
64

  
65
  bool update(double dt, QPainter& path_painter, const QImage& path_image, 
66
	      qreal canvas_width, qreal canvas_height);
67

  
68
  void paint(QPainter &painter);
69

  
70
private:
71
  void turnAngleCallback(const buggymsgs::DirectionConstPtr& dir);
72

  
73
  bool setPenCallback(buggysim::SetPen::Request&, 
74
		      buggysim::SetPen::Response&);
75
  
76
  bool teleportRelativeCallback(buggysim::TeleportRelative::Request&, 
77
				buggysim::TeleportRelative::Response&);
78

  
79
  bool teleportAbsoluteCallback(buggysim::TeleportAbsolute::Request&, 
80
				buggysim::TeleportAbsolute::Response&);
81

  
82
  void rotateImage();
83

  
84
  ros::NodeHandle nh_;
85

  
86
  QImage turtle_image_;
87
  QImage turtle_rotated_image_;
88

  
89
  QPointF pos_;
90
  qreal orient_;
91

  
92
  qreal lin_vel_;
93
  //qreal ang_vel_;
94
  qreal turnAngle_;
95
  bool pen_on_;
96
  QPen pen_;
97

  
98
  ros::Subscriber angle_sub_;
99
  ros::Publisher pose_pub_;
100
  //ros::Publisher color_pub_;
101
  ros::ServiceServer set_pen_srv_;
102
  ros::ServiceServer teleport_relative_srv_;
103
  ros::ServiceServer teleport_absolute_srv_;
104

  
105
  ros::WallTime last_command_time_;
106

  
107
  float meter_;
108

  
109
  struct TeleportRequest
110
  {
111
    TeleportRequest(float x, float y, qreal _theta, qreal _linear, bool _relative)
112
    : pos(x, y)
113
    , theta(_theta)
114
    , linear(_linear)
115
    , relative(_relative)
116
    {}
117

  
118
    QPointF pos;
119
    qreal theta;
120
    qreal linear;
121
    bool relative;
122
  };
123
  typedef std::vector<TeleportRequest> V_TeleportRequest;
124
  V_TeleportRequest teleport_requests_;
125
};
126
typedef boost::shared_ptr<Turtle> TurtlePtr;
57
   class Turtle
58
   {
59
   public:
60
      Turtle(const ros::NodeHandle& nh,
61
             const QImage& turtle_image,
62
             const QPointF& pos,
63
             float orient);
64

  
65
      bool update(double dt, QPainter& path_painter, const QImage& path_image,
66
                  qreal canvas_width, qreal canvas_height);
67

  
68
      void paint(QPainter &painter);
69

  
70
   private:
71
      void turnAngleCallback(const buggymsgs::DirectionConstPtr& dir);
72

  
73
      bool setPenCallback(buggysim::SetPen::Request&,
74
                          buggysim::SetPen::Response&);
75

  
76
      bool teleportRelativeCallback(buggysim::TeleportRelative::Request&,
77
                                    buggysim::TeleportRelative::Response&);
78

  
79
      bool teleportAbsoluteCallback(buggysim::TeleportAbsolute::Request&,
80
                                    buggysim::TeleportAbsolute::Response&);
81

  
82
      void rotateImage();
83

  
84
      ros::NodeHandle nh_;
85

  
86
      QImage turtle_image_;
87
      QImage turtle_rotated_image_;
88

  
89
      QPointF pos_;
90
      qreal orient_;
91

  
92
      qreal lin_vel_;
93
      //qreal ang_vel_;
94
      qreal turnAngle_;
95
      bool pen_on_;
96
      QPen pen_;
97

  
98
      ros::Subscriber angle_sub_;
99
      ros::Publisher pose_pub_;
100
      //ros::Publisher color_pub_;
101
      ros::ServiceServer set_pen_srv_;
102
      ros::ServiceServer teleport_relative_srv_;
103
      ros::ServiceServer teleport_absolute_srv_;
104

  
105
      ros::WallTime last_command_time_;
106

  
107
      float meter_;
108

  
109
      struct TeleportRequest {
110
         TeleportRequest(float x, float y, qreal _theta, qreal _linear, bool _relative)
111
            : pos(x, y)
112
            , theta(_theta)
113
            , linear(_linear)
114
            , relative(_relative)
115
         {}
116

  
117
         QPointF pos;
118
         qreal theta;
119
         qreal linear;
120
         bool relative;
121
      };
122
      typedef std::vector<TeleportRequest> V_TeleportRequest;
123
      V_TeleportRequest teleport_requests_;
124
   };
125
   typedef boost::shared_ptr<Turtle> TurtlePtr;
127 126

  
128 127
}
129 128

  
buggysim/include/buggysim/sim_frame.h
49 49
namespace buggysim
50 50
{
51 51

  
52
class TurtleFrame : public QFrame
53
{
54
  Q_OBJECT
55
public:
56
  TurtleFrame(QWidget* parent = 0, Qt::WindowFlags f = 0);
57
  ~TurtleFrame();
52
   class TurtleFrame : public QFrame
53
   {
54
      Q_OBJECT
55
   public:
56
      TurtleFrame(QWidget* parent = 0, Qt::WindowFlags f = 0);
57
      ~TurtleFrame();
58 58

  
59
  std::string spawnTurtle(const std::string& name, float x, float y, float angle);
59
      std::string spawnTurtle(const std::string& name, float x, float y, float angle);
60 60

  
61
protected:
62
  void paintEvent(QPaintEvent* event);
61
   protected:
62
      void paintEvent(QPaintEvent* event);
63 63

  
64
private slots:
65
  void onUpdate();
64
   private slots:
65
      void onUpdate();
66 66

  
67
private:
68
  void updateTurtles();
69
  void clear();
70
  bool hasTurtle(const std::string& name);
67
   private:
68
      void updateTurtles();
69
      void clear();
70
      bool hasTurtle(const std::string& name);
71 71

  
72
  bool clearCallback(std_srvs::Empty::Request&, std_srvs::Empty::Response&);
73
  bool resetCallback(std_srvs::Empty::Request&, std_srvs::Empty::Response&);
74
  bool spawnCallback(buggysim::Spawn::Request&, buggysim::Spawn::Response&);
75
  bool killCallback(buggysim::Kill::Request&, buggysim::Kill::Response&);
72
      bool clearCallback(std_srvs::Empty::Request&, std_srvs::Empty::Response&);
73
      bool resetCallback(std_srvs::Empty::Request&, std_srvs::Empty::Response&);
74
      bool spawnCallback(buggysim::Spawn::Request&, buggysim::Spawn::Response&);
75
      bool killCallback(buggysim::Kill::Request&, buggysim::Kill::Response&);
76 76

  
77
  ros::NodeHandle nh_;
78
  QTimer* update_timer_;
79
  QImage path_image_;
80
  QPainter path_painter_;
77
      ros::NodeHandle nh_;
78
      QTimer* update_timer_;
79
      QImage path_image_;
80
      QPainter path_painter_;
81 81

  
82
  uint64_t frame_count_;
82
      uint64_t frame_count_;
83 83

  
84
  ros::WallTime last_turtle_update_;
84
      ros::WallTime last_turtle_update_;
85 85

  
86
  ros::ServiceServer clear_srv_;
87
  ros::ServiceServer reset_srv_;
88
  ros::ServiceServer spawn_srv_;
89
  ros::ServiceServer kill_srv_;
86
      ros::ServiceServer clear_srv_;
87
      ros::ServiceServer reset_srv_;
88
      ros::ServiceServer spawn_srv_;
89
      ros::ServiceServer kill_srv_;
90 90

  
91
  typedef std::map<std::string, TurtlePtr> M_Turtle;
92
  M_Turtle turtles_;
93
  uint32_t id_counter_;
91
      typedef std::map<std::string, TurtlePtr> M_Turtle;
92
      M_Turtle turtles_;
93
      uint32_t id_counter_;
94 94

  
95
  QVector<QImage> turtle_images_;
95
      QVector<QImage> turtle_images_;
96 96

  
97
  float meter_;
98
  float width_in_meters_;
99
  float height_in_meters_;
100
};
97
      float meter_;
98
      float width_in_meters_;
99
      float height_in_meters_;
100
   };
101 101

  
102 102
}
buggysim/src/adelaide.cpp
1 1
// This file will contain the details specific to this revision of the
2 2
//  simulator. Most other upgrades (painting, maps, spawning)
3
//  will be in AbstractBuggy. 
4
// This file will focus on being a physics simulation engine. 
3
//  will be in AbstractBuggy.
4
// This file will focus on being a physics simulation engine.
buggysim/src/buggy.cpp
39 39
namespace buggysim
40 40
{
41 41

  
42
Turtle::Turtle(const ros::NodeHandle& nh, const QImage& turtle_image, const QPointF& pos, float orient)
43
: nh_(nh)
44
, turtle_image_(turtle_image)
45
, pos_(pos)
46
, orient_(orient)
47
, lin_vel_(2.0)
48
  //, ang_vel_(0.0)
49
, turnAngle_(0.0)
50
, pen_on_(true)
51
, pen_(QColor(DEFAULT_PEN_R, DEFAULT_PEN_G, DEFAULT_PEN_B))
52
{
53
  pen_.setWidth(3);
54

  
55
  angle_sub_ = nh_.subscribe
56
         ("command_turnAngle", 1, &Turtle::turnAngleCallback, this);
57
  pose_pub_ = nh_.advertise<buggymsgs::Pose>("pose", 1);
58

  
59
  //color_pub_ = nh_.advertise<Color>("color_sensor", 1);
60
  set_pen_srv_ = nh_.advertiseService
61
         ("set_pen", &Turtle::setPenCallback, this);
62
  teleport_relative_srv_ = nh_.advertiseService
63
         ("teleport_relative", &Turtle::teleportRelativeCallback, this);
64
  teleport_absolute_srv_ = nh_.advertiseService
65
         ("teleport_absolute", &Turtle::teleportAbsoluteCallback, this);
66

  
67
  meter_ = turtle_image_.height();
68
  rotateImage();
69
}
70

  
71

  
72
void Turtle::turnAngleCallback(const buggymsgs::DirectionConstPtr& dir)
73
{
74
  last_command_time_ = ros::WallTime::now();
75
  turnAngle_ = dir->turnAngle;
76
  //lin_vel_ = vel->linear;
77
  //ang_vel_ = vel->angular;
78
}
79
  
80
bool Turtle::setPenCallback(buggysim::SetPen::Request& req, 
81
			    buggysim::SetPen::Response&)
82
{
83
  pen_on_ = !req.off;
84
  if (req.off)
85
  {
86
    return true;
87
  }
88

  
89
  QPen pen(QColor(req.r, req.g, req.b));
90
  if (req.width != 0)
91
  {
92
    pen.setWidth(req.width);
93
  }
94

  
95
  pen_ = pen;
96
  return true;
97
}
98

  
99
bool Turtle::teleportRelativeCallback(buggysim::TeleportRelative::Request& req, 
100
				      buggysim::TeleportRelative::Response&)
101
{
102
  teleport_requests_.push_back(TeleportRequest(0, 0, req.angular, req.linear, true));
103
  return true;
104
}
105

  
106
bool Turtle::teleportAbsoluteCallback(buggysim::TeleportAbsolute::Request& req, 
107
				      buggysim::TeleportAbsolute::Response&)
108
{
109
  teleport_requests_.push_back(TeleportRequest(req.x, req.y, req.theta, 0, false));
110
  return true;
111
}
112

  
113
void Turtle::rotateImage()
114
{
115
  QTransform transform;
116
  transform.rotate(-orient_ * 180.0 / PI + 90.0);
117
  turtle_rotated_image_ = turtle_image_.transformed(transform);
118
}
119

  
120
/**
121
 * TODO: convert this to take just an angle. And include drag. 
122
 *       and include acceleration/joule dump
123
 */
124
bool Turtle::update(double dt, QPainter& path_painter, const QImage& path_image, qreal canvas_width, qreal canvas_height)
125
{
126
  bool modified = false;
127
  qreal old_orient = orient_;
128

  
129
  // first process any teleportation requests, in order
130
  V_TeleportRequest::iterator it = teleport_requests_.begin();
131
  V_TeleportRequest::iterator end = teleport_requests_.end();
132
  for (; it != end; ++it)
133
  {
134
    const TeleportRequest& req = *it;
135

  
136
    QPointF old_pos = pos_;
137
    if (req.relative)
138
    {
139
      orient_ += req.theta;
140
      pos_.rx() += std::sin(orient_ + PI/2.0) * req.linear;
141
      pos_.ry() += std::cos(orient_ + PI/2.0) * req.linear;
142
    }
143
    else
144
    {
145
      pos_.setX(req.pos.x());
146
      pos_.setY(std::max(0.0, static_cast<double>(canvas_height - req.pos.y())));
147
      orient_ = req.theta;
148
    }
149

  
150
    path_painter.setPen(pen_);
151
    path_painter.drawLine(pos_ * meter_, old_pos * meter_);
152
    modified = true;
153
  }
154

  
155
  teleport_requests_.clear();
156

  
157
  // Stop moving after 1 second since-last command.
158
  //if (ros::WallTime::now() - last_command_time_ > ros::WallDuration(1.0))
159
  //{
160
  //  lin_vel_ = 0.0;
161
  //  ang_vel_ = 0.0;
162
  //}
163

  
164
  // Update my position
165
  QPointF old_pos = pos_;
166

  
167
  /* Convert coordinate systens
168
  orient_ = std::fmod(orient_ + ang_vel_ * dt, 2*PI);
169
  pos_.rx() += std::sin(orient_ + PI/2.0) * lin_vel_ * dt;
170
  pos_.ry() += std::cos(orient_ + PI/2.0) * lin_vel_ * dt;
171
  */
172
  // TODO: what direction does orientation start at 0?
173
  // TODO: orient might have to become negative
174
  orient_ = std::fmod(orient_ - turnAngle_ * dt, 2*PI);
175
  // TODO: why add pi/2? is this just because they got the 
176
  //       sin/cos mixed up?
177
  //pos_.rx() += std::sin(orient_ + PI/2.0) * lin_vel_ * dt;
178
  //pos_.ry() += std::cos(orient_ + PI/2.0) * lin_vel_ * dt;
179

  
180
  pos_.rx() += std::cos(orient_) * lin_vel_ * dt;
181
  pos_.ry() += std::sin(orient_) * lin_vel_ * dt;
182

  
183

  
184
  // Find linear velocity
185
  //qreal lin_vel;
186
  // Find angular velocity
187
  //qreal ang_vel;
188

  
189
  // Clamp to screen size
190
  // TODO: change to use another image, to detect walls. 
191
  if (pos_.x() < 0 || pos_.x() > canvas_width ||
192
      pos_.y() < 0 || pos_.y() > canvas_height)
193
  {
194
    ROS_WARN("Oh no! I hit the wall! (Clamping from [x=%f, y=%f])", pos_.x(), pos_.y());
195
  }
196

  
197
  pos_.setX(std::min(std::max(static_cast<double>(pos_.x()), 0.0), 
198
                             static_cast<double>(canvas_width)));
199
  pos_.setY(std::min(std::max(static_cast<double>(pos_.y()), 0.0), 
200
		             static_cast<double>(canvas_height)));
201

  
202
  // Publish pose of the turtle
203
  buggymsgs::Pose p;
204
  p.x = pos_.x();
205
  p.y = canvas_height - pos_.y();
206
  p.angle = orient_;
207
  p.linear_velocity = lin_vel_;
208
  //p.angular_velocity = ang_vel;
209
  pose_pub_.publish(p);
210

  
211
  // Figure out (and publish) the color underneath the turtle
212
  /*{
213
    Color color;
214
    QRgb pixel = path_image.pixel((pos_ * meter_).toPoint());
215
    color.r = qRed(pixel);
216
    color.g = qGreen(pixel);
217
    color.b = qBlue(pixel);
218
    color_pub_.publish(color);
219
    }*/
220

  
221
  ROS_DEBUG("[%s]: pos_x: %f pos_y: %f theta: %f", nh_.getNamespace().c_str(), pos_.x(), pos_.y(), orient_);
222

  
223
  if (orient_ != old_orient)
224
  {
225
    rotateImage();
226
    modified = true;
227
  }
228
  if (pos_ != old_pos)
229
  {
230
    if (pen_on_)
231
    {
232
      path_painter.setPen(pen_);
233
      path_painter.drawLine(pos_ * meter_, old_pos * meter_);
234
    }
235
    modified = true;
236
  }
237

  
238
  return modified;
239
}
240

  
241
void Turtle::paint(QPainter& painter)
242
{
243
  QPointF p = pos_ * meter_;
244
  p.rx() -= 0.5 * turtle_rotated_image_.width();
245
  p.ry() -= 0.5 * turtle_rotated_image_.height();
246
  painter.drawImage(p, turtle_rotated_image_);
247
}
42
   Turtle::Turtle(const ros::NodeHandle& nh, const QImage& turtle_image,
43
                  const QPointF& pos, float orient)
44
      : nh_(nh)
45
      , turtle_image_(turtle_image)
46
      , pos_(pos)
47
      , orient_(orient)
48
      , lin_vel_(2.0)
49
      //, ang_vel_(0.0)
50
      , turnAngle_(0.0)
51
      , pen_on_(true)
52
      , pen_(QColor(DEFAULT_PEN_R, DEFAULT_PEN_G, DEFAULT_PEN_B))
53
   {
54
      pen_.setWidth(3);
55

  
56
      angle_sub_ = nh_.subscribe
57
                   ("command_turnAngle", 1, &Turtle::turnAngleCallback, this);
58
      pose_pub_ = nh_.advertise<buggymsgs::Pose>("pose", 1);
59

  
60
      //color_pub_ = nh_.advertise<Color>("color_sensor", 1);
61
      set_pen_srv_ = nh_.advertiseService
62
                     ("set_pen", &Turtle::setPenCallback, this);
63
      teleport_relative_srv_ = nh_.advertiseService
64
                               ("teleport_relative", &Turtle::teleportRelativeCallback, this);
65
      teleport_absolute_srv_ = nh_.advertiseService
66
                               ("teleport_absolute", &Turtle::teleportAbsoluteCallback, this);
67

  
68
      meter_ = turtle_image_.height();
69
      rotateImage();
70
   }
71

  
72

  
73
   void Turtle::turnAngleCallback(const buggymsgs::DirectionConstPtr& dir)
74
   {
75
      last_command_time_ = ros::WallTime::now();
76
      turnAngle_ = dir->turnAngle;
77
      //lin_vel_ = vel->linear;
78
      //ang_vel_ = vel->angular;
79
   }
80

  
81
   bool Turtle::setPenCallback(buggysim::SetPen::Request& req,
82
                               buggysim::SetPen::Response&)
83
   {
84
      pen_on_ = !req.off;
85
      if (req.off) {
86
         return true;
87
      }
88

  
89
      QPen pen(QColor(req.r, req.g, req.b));
90
      if (req.width != 0) {
91
         pen.setWidth(req.width);
92
      }
93

  
94
      pen_ = pen;
95
      return true;
96
   }
97

  
98
   bool Turtle::teleportRelativeCallback(buggysim::TeleportRelative::Request& req,
99
                                         buggysim::TeleportRelative::Response&)
100
   {
101
      teleport_requests_.push_back(TeleportRequest(0, 0, req.angular, req.linear,
102
                                   true));
103
      return true;
104
   }
105

  
106
   bool Turtle::teleportAbsoluteCallback(buggysim::TeleportAbsolute::Request& req,
107
                                         buggysim::TeleportAbsolute::Response&)
108
   {
109
      teleport_requests_.push_back(TeleportRequest(req.x, req.y, req.theta, 0,
110
                                   false));
111
      return true;
112
   }
113

  
114
   void Turtle::rotateImage()
115
   {
116
      QTransform transform;
117
      transform.rotate(-orient_ * 180.0 / PI + 90.0);
118
      turtle_rotated_image_ = turtle_image_.transformed(transform);
119
   }
120

  
121
   /**
122
    * TODO: convert this to take just an angle. And include drag.
123
    *       and include acceleration/joule dump
124
    */
125
   bool Turtle::update(double dt, QPainter& path_painter, const QImage& path_image,
126
                       qreal canvas_width, qreal canvas_height)
127
   {
128
      bool modified = false;
129
      qreal old_orient = orient_;
130

  
131
      // first process any teleportation requests, in order
132
      V_TeleportRequest::iterator it = teleport_requests_.begin();
133
      V_TeleportRequest::iterator end = teleport_requests_.end();
134
      for (; it != end; ++it) {
135
         const TeleportRequest& req = *it;
136

  
137
         QPointF old_pos = pos_;
138
         if (req.relative) {
139
            orient_ += req.theta;
140
            pos_.rx() += std::sin(orient_ + PI/2.0) * req.linear;
141
            pos_.ry() += std::cos(orient_ + PI/2.0) * req.linear;
142
         } else {
143
            pos_.setX(req.pos.x());
144
            pos_.setY(std::max(0.0, static_cast<double>(canvas_height - req.pos.y())));
145
            orient_ = req.theta;
146
         }
147

  
148
         path_painter.setPen(pen_);
149
         path_painter.drawLine(pos_ * meter_, old_pos * meter_);
150
         modified = true;
151
      }
152

  
153
      teleport_requests_.clear();
154

  
155
      // Stop moving after 1 second since-last command.
156
      //if (ros::WallTime::now() - last_command_time_ > ros::WallDuration(1.0))
157
      //{
158
      //  lin_vel_ = 0.0;
159
      //  ang_vel_ = 0.0;
160
      //}
161

  
162
      // Update my position
163
      QPointF old_pos = pos_;
164

  
165
      /* Convert coordinate systens
166
      orient_ = std::fmod(orient_ + ang_vel_ * dt, 2*PI);
167
      pos_.rx() += std::sin(orient_ + PI/2.0) * lin_vel_ * dt;
168
      pos_.ry() += std::cos(orient_ + PI/2.0) * lin_vel_ * dt;
169
      */
170
      // TODO: what direction does orientation start at 0?
171
      // TODO: orient might have to become negative
172
      orient_ = std::fmod(orient_ - turnAngle_ * dt, 2*PI);
173
      // TODO: why add pi/2? is this just because they got the
174
      //       sin/cos mixed up?
175
      //pos_.rx() += std::sin(orient_ + PI/2.0) * lin_vel_ * dt;
176
      //pos_.ry() += std::cos(orient_ + PI/2.0) * lin_vel_ * dt;
177

  
178
      pos_.rx() += std::cos(orient_) * lin_vel_ * dt;
179
      pos_.ry() += std::sin(orient_) * lin_vel_ * dt;
180

  
181

  
182
      // Find linear velocity
183
      //qreal lin_vel;
184
      // Find angular velocity
185
      //qreal ang_vel;
186

  
187
      // Clamp to screen size
188
      // TODO: change to use another image, to detect walls.
189
      if (pos_.x() < 0 || pos_.x() > canvas_width ||
190
            pos_.y() < 0 || pos_.y() > canvas_height) {
191
         ROS_WARN("Oh no! I hit the wall! (Clamping from [x=%f, y=%f])", pos_.x(),
192
                  pos_.y());
193
      }
194

  
195
      pos_.setX(std::min(std::max(static_cast<double>(pos_.x()), 0.0),
196
                         static_cast<double>(canvas_width)));
197
      pos_.setY(std::min(std::max(static_cast<double>(pos_.y()), 0.0),
198
                         static_cast<double>(canvas_height)));
199

  
200
      // Publish pose of the turtle
201
      buggymsgs::Pose p;
202
      p.x = pos_.x();
203
      p.y = canvas_height - pos_.y();
204
      p.angle = orient_;
205
      p.linear_velocity = lin_vel_;
206
      //p.angular_velocity = ang_vel;
207
      pose_pub_.publish(p);
208

  
209
      // Figure out (and publish) the color underneath the turtle
210
      /*{
211
        Color color;
212
        QRgb pixel = path_image.pixel((pos_ * meter_).toPoint());
213
        color.r = qRed(pixel);
214
        color.g = qGreen(pixel);
215
        color.b = qBlue(pixel);
216
        color_pub_.publish(color);
217
        }*/
218

  
219
      ROS_DEBUG("[%s]: pos_x: %f pos_y: %f theta: %f", nh_.getNamespace().c_str(),
220
                pos_.x(), pos_.y(), orient_);
221

  
222
      if (orient_ != old_orient) {
223
         rotateImage();
224
         modified = true;
225
      }
226
      if (pos_ != old_pos) {
227
         if (pen_on_) {
228
            path_painter.setPen(pen_);
229
            path_painter.drawLine(pos_ * meter_, old_pos * meter_);
230
         }
231
         modified = true;
232
      }
233

  
234
      return modified;
235
   }
236

  
237
   void Turtle::paint(QPainter& painter)
238
   {
239
      QPointF p = pos_ * meter_;
240
      p.rx() -= 0.5 * turtle_rotated_image_.width();
241
      p.ry() -= 0.5 * turtle_rotated_image_.height();
242
      painter.drawImage(p, turtle_rotated_image_);
243
   }
248 244

  
249 245
}
buggysim/src/buggysim.cpp
36 36
class TurtleApp : public QApplication
37 37
{
38 38
public:
39
  ros::NodeHandlePtr nh_;
40

  
41
  TurtleApp(int& argc, char** argv)
42
    : QApplication(argc, argv)
43
  {
44
    ros::init(argc, argv, "buggysim", ros::init_options::NoSigintHandler);
45
    nh_.reset(new ros::NodeHandle);
46
  }
47

  
48
  int exec()
49
  {
50
    buggysim::TurtleFrame frame;
51
    frame.show();
52

  
53
    return QApplication::exec();
54
  }
39
   ros::NodeHandlePtr nh_;
40

  
41
   TurtleApp(int& argc, char** argv)
42
      : QApplication(argc, argv)
43
   {
44
      ros::init(argc, argv, "buggysim", ros::init_options::NoSigintHandler);
45
      nh_.reset(new ros::NodeHandle);
46
   }
47

  
48
   int exec()
49
   {
50
      buggysim::TurtleFrame frame;
51
      frame.show();
52

  
53
      return QApplication::exec();
54
   }
55 55
};
56 56

  
57 57
int main(int argc, char** argv)
58 58
{
59
  TurtleApp app(argc, argv);
60
  return app.exec();
59
   TurtleApp app(argc, argv);
60
   return app.exec();
61 61
}
62 62

  
buggysim/src/sim_frame.cpp
42 42
namespace buggysim
43 43
{
44 44

  
45
TurtleFrame::TurtleFrame(QWidget* parent, Qt::WindowFlags f)
46
: QFrame(parent, f)
47
, path_image_(500, 500, QImage::Format_ARGB32)
48
, path_painter_(&path_image_)
49
, frame_count_(0)
50
, id_counter_(0)
51
{
52
  setFixedSize(500, 500);
53
  setWindowTitle("BuggySim Frame!");
54

  
55
  srand(time(NULL));
56

  
57
  update_timer_ = new QTimer(this);
58
  update_timer_->setInterval(16);
59
  update_timer_->start();
60

  
61
  connect(update_timer_, SIGNAL(timeout()), this, SLOT(onUpdate()));
62

  
63
  nh_.setParam("background_r", DEFAULT_BG_R);
64
  nh_.setParam("background_g", DEFAULT_BG_G);
65
  nh_.setParam("background_b", DEFAULT_BG_B);
66

  
67
  QVector<QString> turtles;
68
  turtles.append("box-turtle.png");
69
  turtles.append("robot-turtle.png");
70
  turtles.append("sea-turtle.png");
71
  turtles.append("diamondback.png");
72
  turtles.append("electric.png");
73
  turtles.append("fuerte.png");
74
  turtles.append("groovy.png");
75
  turtles.append("hydro.svg");
76

  
77
  QString images_path = (ros::package::getPath("buggysim") + "/images/").c_str();
78
  for (size_t i = 0; i < turtles.size(); ++i)
79
  {
80
    QImage img;
81
    img.load(images_path + turtles[i]);
82
    turtle_images_.append(img);
83
  }
84

  
85
  meter_ = turtle_images_[0].height();
86

  
87
  clear();
88

  
89
  clear_srv_ = nh_.advertiseService("clear", &TurtleFrame::clearCallback, this);
90
  reset_srv_ = nh_.advertiseService("reset", &TurtleFrame::resetCallback, this);
91
  spawn_srv_ = nh_.advertiseService("spawn", &TurtleFrame::spawnCallback, this);
92
  kill_srv_ = nh_.advertiseService("kill", &TurtleFrame::killCallback, this);
93

  
94
  ROS_INFO("Starting buggysim with node name %s", ros::this_node::getName().c_str()) ;
95

  
96
  width_in_meters_ = (width() - 1) / meter_;
97
  height_in_meters_ = (height() - 1) / meter_;
98
  spawnTurtle("", width_in_meters_ / 2.0, height_in_meters_ / 2.0, 0);
99
}
100

  
101
TurtleFrame::~TurtleFrame()
102
{
103
  delete update_timer_;
104
}
105

  
106
bool TurtleFrame::spawnCallback(buggysim::Spawn::Request& req, buggysim::Spawn::Response& res)
107
{
108
  std::string name = spawnTurtle(req.name, req.x, req.y, req.theta);
109
  if (name.empty())
110
  {
111
    ROS_ERROR("A turtled named [%s] already exists", req.name.c_str());
112
    return false;
113
  }
114

  
115
  res.name = name;
116

  
117
  return true;
118
}
119

  
120
bool TurtleFrame::killCallback(buggysim::Kill::Request& req, buggysim::Kill::Response&)
121
{
122
  M_Turtle::iterator it = turtles_.find(req.name);
123
  if (it == turtles_.end())
124
  {
125
    ROS_ERROR("Tried to kill turtle [%s], which does not exist", req.name.c_str());
126
    return false;
127
  }
128

  
129
  turtles_.erase(it);
130
  update();
131

  
132
  return true;
133
}
134

  
135
bool TurtleFrame::hasTurtle(const std::string& name)
136
{
137
  return turtles_.find(name) != turtles_.end();
138
}
139

  
140
std::string TurtleFrame::spawnTurtle(const std::string& name, float x, float y, float angle)
141
{
142
  std::string real_name = name;
143
  if (real_name.empty()) {
144
    do {
145
      std::stringstream ss;
146
      // TODO: change how turtles are spawned
147
      ss << "buggy" << ++id_counter_;
148
      real_name = ss.str();
149
    } while (hasTurtle(real_name));
150
  }
151
  else {
152
    if (hasTurtle(real_name)) {
153
      return "";
154
    }
155
  }
156

  
157
  TurtlePtr t(new Turtle(ros::NodeHandle(real_name), turtle_images_[rand() % turtle_images_.size()], QPointF(x, y), angle));
158
  turtles_[real_name] = t;
159
  update();
160

  
161
  ROS_INFO("Spawning turtle [%s] at x=[%f], y=[%f], theta=[%f]", real_name.c_str(), x, y, angle);
162

  
163
  return real_name;
164
}
165

  
166
void TurtleFrame::clear()
167
{
168
  int r = DEFAULT_BG_R;
169
  int g = DEFAULT_BG_G;
170
  int b = DEFAULT_BG_B;
171

  
172
  nh_.param("background_r", r, r);
173
  nh_.param("background_g", g, g);
174
  nh_.param("background_b", b, b);
175

  
176
  path_image_.fill(qRgb(r, g, b));
177
  update();
178
}
179

  
180
void TurtleFrame::onUpdate()
181
{
182
  ros::spinOnce();
183

  
184
  updateTurtles();
185

  
186
  if (!ros::ok())
187
  {
188
    close();
189
  }
190
}
191

  
192
void TurtleFrame::paintEvent(QPaintEvent* event)
193
{
194
  QPainter painter(this);
195

  
196
  painter.drawImage(QPoint(0, 0), path_image_);
197

  
198
  M_Turtle::iterator it = turtles_.begin();
199
  M_Turtle::iterator end = turtles_.end();
200
  for (; it != end; ++it)
201
  {
202
    it->second->paint(painter);
203
  }
204
}
205

  
206
void TurtleFrame::updateTurtles()
207
{
208
  if (last_turtle_update_.isZero())
209
  {
210
    last_turtle_update_ = ros::WallTime::now();
211
    return;
212
  }
213

  
214
  bool modified = false;
215
  M_Turtle::iterator it = turtles_.begin();
216
  M_Turtle::iterator end = turtles_.end();
217
  for (; it != end; ++it)
218
  {
219
    modified |= it->second->update(0.001 * update_timer_->interval(), path_painter_, path_image_, width_in_meters_, height_in_meters_);
220
  }
221
  if (modified)
222
  {
223
    update();
224
  }
225

  
226
  ++frame_count_;
227
}
228

  
229

  
230
bool TurtleFrame::clearCallback(std_srvs::Empty::Request&, std_srvs::Empty::Response&)
231
{
232
  ROS_INFO("Clearing turtlesim.");
233
  clear();
234
  return true;
235
}
236

  
237
bool TurtleFrame::resetCallback(std_srvs::Empty::Request&, std_srvs::Empty::Response&)
238
{
239
  ROS_INFO("Resetting turtlesim.");
240
  turtles_.clear();
241
  id_counter_ = 0;
242
  spawnTurtle("", width_in_meters_ / 2.0, height_in_meters_ / 2.0, 0);
243
  clear();
244
  return true;
245
}
45
   TurtleFrame::TurtleFrame(QWidget* parent, Qt::WindowFlags f)
46
      : QFrame(parent, f)
47
      , path_image_(500, 500, QImage::Format_ARGB32)
48
      , path_painter_(&path_image_)
49
      , frame_count_(0)
50
      , id_counter_(0)
51
   {
52
      setFixedSize(500, 500);
53
      setWindowTitle("BuggySim Frame!");
54

  
55
      srand(time(NULL));
56

  
57
      update_timer_ = new QTimer(this);
58
      update_timer_->setInterval(16);
59
      update_timer_->start();
60

  
61
      connect(update_timer_, SIGNAL(timeout()), this, SLOT(onUpdate()));
62

  
63
      nh_.setParam("background_r", DEFAULT_BG_R);
64
      nh_.setParam("background_g", DEFAULT_BG_G);
65
      nh_.setParam("background_b", DEFAULT_BG_B);
66

  
67
      QVector<QString> turtles;
68
      turtles.append("box-turtle.png");
69
      turtles.append("robot-turtle.png");
70
      turtles.append("sea-turtle.png");
71
      turtles.append("diamondback.png");
72
      turtles.append("electric.png");
73
      turtles.append("fuerte.png");
74
      turtles.append("groovy.png");
75
      turtles.append("hydro.svg");
76

  
77
      QString images_path = (ros::package::getPath("buggysim") + "/images/").c_str();
78
      for (size_t i = 0; i < turtles.size(); ++i) {
79
         QImage img;
80
         img.load(images_path + turtles[i]);
81
         turtle_images_.append(img);
82
      }
83

  
84
      meter_ = turtle_images_[0].height();
85

  
86
      clear();
87

  
88
      clear_srv_ = nh_.advertiseService("clear", &TurtleFrame::clearCallback, this);
89
      reset_srv_ = nh_.advertiseService("reset", &TurtleFrame::resetCallback, this);
90
      spawn_srv_ = nh_.advertiseService("spawn", &TurtleFrame::spawnCallback, this);
91
      kill_srv_ = nh_.advertiseService("kill", &TurtleFrame::killCallback, this);
92

  
93
      ROS_INFO("Starting buggysim with node name %s",
94
               ros::this_node::getName().c_str()) ;
95

  
96
      width_in_meters_ = (width() - 1) / meter_;
97
      height_in_meters_ = (height() - 1) / meter_;
98
      spawnTurtle("", width_in_meters_ / 2.0, height_in_meters_ / 2.0, 0);
99
   }
100

  
101
   TurtleFrame::~TurtleFrame()
102
   {
103
      delete update_timer_;
104
   }
105

  
106
   bool TurtleFrame::spawnCallback(buggysim::Spawn::Request& req,
107
                                   buggysim::Spawn::Response& res)
108
   {
109
      std::string name = spawnTurtle(req.name, req.x, req.y, req.theta);
110
      if (name.empty()) {
111
         ROS_ERROR("A turtled named [%s] already exists", req.name.c_str());
112
         return false;
113
      }
114

  
115
      res.name = name;
116

  
117
      return true;
118
   }
119

  
120
   bool TurtleFrame::killCallback(buggysim::Kill::Request& req,
121
                                  buggysim::Kill::Response&)
122
   {
123
      M_Turtle::iterator it = turtles_.find(req.name);
124
      if (it == turtles_.end()) {
125
         ROS_ERROR("Tried to kill turtle [%s], which does not exist", req.name.c_str());
126
         return false;
127
      }
128

  
129
      turtles_.erase(it);
130
      update();
131

  
132
      return true;
133
   }
134

  
135
   bool TurtleFrame::hasTurtle(const std::string& name)
136
   {
137
      return turtles_.find(name) != turtles_.end();
138
   }
139

  
140
   std::string TurtleFrame::spawnTurtle(const std::string& name, float x, float y,
141
                                        float angle)
142
   {
143
      std::string real_name = name;
144
      if (real_name.empty()) {
145
         do {
146
            std::stringstream ss;
147
            // TODO: change how turtles are spawned
148
            ss << "buggy" << ++id_counter_;
149
            real_name = ss.str();
150
         } while (hasTurtle(real_name));
151
      } else {
152
         if (hasTurtle(real_name)) {
153
            return "";
154
         }
155
      }
156

  
157
      TurtlePtr t(new Turtle(ros::NodeHandle(real_name),
158
                             turtle_images_[rand() % turtle_images_.size()], QPointF(x, y), angle));
159
      turtles_[real_name] = t;
160
      update();
161

  
162
      ROS_INFO("Spawning turtle [%s] at x=[%f], y=[%f], theta=[%f]",
163
               real_name.c_str(), x, y, angle);
164

  
165
      return real_name;
166
   }
167

  
168
   void TurtleFrame::clear()
169
   {
170
      int r = DEFAULT_BG_R;
171
      int g = DEFAULT_BG_G;
172
      int b = DEFAULT_BG_B;
173

  
174
      nh_.param("background_r", r, r);
175
      nh_.param("background_g", g, g);
176
      nh_.param("background_b", b, b);
177

  
178
      path_image_.fill(qRgb(r, g, b));
179
      update();
180
   }
181

  
182
   void TurtleFrame::onUpdate()
183
   {
184
      ros::spinOnce();
185

  
186
      updateTurtles();
187

  
188
      if (!ros::ok()) {
189
         close();
190
      }
191
   }
192

  
193
   void TurtleFrame::paintEvent(QPaintEvent* event)
194
   {
195
      QPainter painter(this);
196

  
197
      painter.drawImage(QPoint(0, 0), path_image_);
198

  
199
      M_Turtle::iterator it = turtles_.begin();
200
      M_Turtle::iterator end = turtles_.end();
201
      for (; it != end; ++it) {
202
         it->second->paint(painter);
203
      }
204
   }
205

  
206
   void TurtleFrame::updateTurtles()
207
   {
208
      if (last_turtle_update_.isZero()) {
209
         last_turtle_update_ = ros::WallTime::now();
210
         return;
211
      }
212

  
213
      bool modified = false;
214
      M_Turtle::iterator it = turtles_.begin();
215
      M_Turtle::iterator end = turtles_.end();
216
      for (; it != end; ++it) {
217
         modified |= it->second->update(0.001 * update_timer_->interval(), path_painter_,
218
                                        path_image_, width_in_meters_, height_in_meters_);
219
      }
220
      if (modified) {
221
         update();
222
      }
223

  
224
      ++frame_count_;
225
   }
226

  
227

  
228
   bool TurtleFrame::clearCallback(std_srvs::Empty::Request&,
229
                                   std_srvs::Empty::Response&)
230
   {
231
      ROS_INFO("Clearing turtlesim.");
232
      clear();
233
      return true;
234
   }
235

  
236
   bool TurtleFrame::resetCallback(std_srvs::Empty::Request&,
237
                                   std_srvs::Empty::Response&)
238
   {
239
      ROS_INFO("Resetting turtlesim.");
240
      turtles_.clear();
241
      id_counter_ = 0;
242
      spawnTurtle("", width_in_meters_ / 2.0, height_in_meters_ / 2.0, 0);
243
      clear();
244
      return true;
245
   }
246 246

  
247 247
}
buggysim/tutorials/draw_square.cpp
7 7
turtlesim::PoseConstPtr g_pose;
8 8
turtlesim::Pose g_goal;
9 9

  
10
enum State
11
{
12
  FORWARD,
13
  STOP_FORWARD,
14
  TURN,
15
  STOP_TURN,
10
enum State {
11
   FORWARD,
12
   STOP_FORWARD,
13
   TURN,
14
   STOP_TURN,
16 15
};
17 16

  
18 17
State g_state = FORWARD;
......
23 22

  
24 23
void poseCallback(const turtlesim::PoseConstPtr& pose)
25 24
{
26
  g_pose = pose;
25
   g_pose = pose;
27 26
}
28 27

  
29 28
bool hasReachedGoal()
30 29
{
31
  return fabsf(g_pose->x - g_goal.x) < 0.1 && fabsf(g_pose->y - g_goal.y) < 0.1 && fabsf(g_pose->theta - g_goal.theta) < 0.01;
30
   return fabsf(g_pose->x - g_goal.x) < 0.1 && fabsf(g_pose->y - g_goal.y) < 0.1
31
          && fabsf(g_pose->theta - g_goal.theta) < 0.01;
32 32
}
33 33

  
34 34
bool hasStopped()
35 35
{
36
  return g_pose->angular_velocity < 0.0001 && g_pose->linear_velocity < 0.0001;
36
   return g_pose->angular_velocity < 0.0001 && g_pose->linear_velocity < 0.0001;
37 37
}
38 38

  
39 39
void printGoal()
40 40
{
41
  ROS_INFO("New goal [%f %f, %f]", g_goal.x, g_goal.y, g_goal.theta);
41
   ROS_INFO("New goal [%f %f, %f]", g_goal.x, g_goal.y, g_goal.theta);
42 42
}
43 43

  
44 44
void commandTurtle(ros::Publisher vel_pub, float linear, float angular)
45 45
{
46
  turtlesim::Velocity vel;
47
  vel.linear = linear;
48
  vel.angular = angular;
49
  vel_pub.publish(vel);
46
   turtlesim::Velocity vel;
47
   vel.linear = linear;
48
   vel.angular = angular;
49
   vel_pub.publish(vel);
50 50
}
51 51

  
52 52
void stopForward(ros::Publisher vel_pub)
53 53
{
54
  if (hasStopped())
55
  {
56
    ROS_INFO("Reached goal");
57
    g_state = TURN;
58
    g_goal.x = g_pose->x;
59
    g_goal.y = g_pose->y;
60
    g_goal.theta = fmod(g_pose->theta + PI/2.0, 2*PI);
61
    printGoal();
62
  }
63
  else
64
  {
65
    commandTurtle(vel_pub, 0, 0);
66
  }
54
   if (hasStopped()) {
55
      ROS_INFO("Reached goal");
56
      g_state = TURN;
57
      g_goal.x = g_pose->x;
58
      g_goal.y = g_pose->y;
59
      g_goal.theta = fmod(g_pose->theta + PI/2.0, 2*PI);
60
      printGoal();
61
   } else {
62
      commandTurtle(vel_pub, 0, 0);
63
   }
67 64
}
68 65

  
69 66
void stopTurn(ros::Publisher vel_pub)
70 67
{
71
  if (hasStopped())
72
  {
73
    ROS_INFO("Reached goal");
74
    g_state = FORWARD;
75
    g_goal.x = cos(g_pose->theta) * 2 + g_pose->x;
76
    g_goal.y = sin(g_pose->theta) * 2 + g_pose->y;
77
    g_goal.theta = g_pose->theta;
78
    printGoal();
79
  }
80
  else
81
  {
82
    commandTurtle(vel_pub, 0, 0);
83
  }
68
   if (hasStopped()) {
69
      ROS_INFO("Reached goal");
70
      g_state = FORWARD;
71
      g_goal.x = cos(g_pose->theta) * 2 + g_pose->x;
72
      g_goal.y = sin(g_pose->theta) * 2 + g_pose->y;
73
      g_goal.theta = g_pose->theta;
74
      printGoal();
75
   } else {
76
      commandTurtle(vel_pub, 0, 0);
77
   }
84 78
}
85 79

  
86 80

  
87 81
void forward(ros::Publisher vel_pub)
88 82
{
89
  if (hasReachedGoal())
90
  {
91
    g_state = STOP_FORWARD;
92
    commandTurtle(vel_pub, 0, 0);
93
  }
94
  else
95
  {
96
    commandTurtle(vel_pub, 1.0, 0.0);
97
  }
83
   if (hasReachedGoal()) {
84
      g_state = STOP_FORWARD;
85
      commandTurtle(vel_pub, 0, 0);
86
   } else {
87
      commandTurtle(vel_pub, 1.0, 0.0);
88
   }
98 89
}
99 90

  
100 91
void turn(ros::Publisher vel_pub)
101 92
{
102
  if (hasReachedGoal())
103
  {
104
    g_state = STOP_TURN;
105
    commandTurtle(vel_pub, 0, 0);
106
  }
107
  else
108
  {
109
    commandTurtle(vel_pub, 0.0, 0.4);
110
  }
93
   if (hasReachedGoal()) {
94
      g_state = STOP_TURN;
95
      commandTurtle(vel_pub, 0, 0);
96
   } else {
97
      commandTurtle(vel_pub, 0.0, 0.4);
98
   }
111 99
}
112 100

  
113 101
void timerCallback(const ros::TimerEvent&, ros::Publisher vel_pub)
114 102
{
115
  if (!g_pose)
116
  {
117
    return;
118
  }
119

  
120
  if (!g_first_goal_set)
121
  {
122
    g_first_goal_set = true;
123
    g_state = FORWARD;
124
    g_goal.x = cos(g_pose->theta) * 2 + g_pose->x;
125
    g_goal.y = sin(g_pose->theta) * 2 + g_pose->y;
126
    g_goal.theta = g_pose->theta;
127
    printGoal();
128
  }
129

  
130
  if (g_state == FORWARD)
131
  {
132
    forward(vel_pub);
133
  }
134
  else if (g_state == STOP_FORWARD)
135
  {
136
    stopForward(vel_pub);
137
  }
138
  else if (g_state == TURN)
139
  {
140
    turn(vel_pub);
141
  }
142
  else if (g_state == STOP_TURN)
143
  {
144
    stopTurn(vel_pub);
145
  }
103
   if (!g_pose) {
104
      return;
105
   }
106

  
107
   if (!g_first_goal_set) {
108
      g_first_goal_set = true;
109
      g_state = FORWARD;
110
      g_goal.x = cos(g_pose->theta) * 2 + g_pose->x;
111
      g_goal.y = sin(g_pose->theta) * 2 + g_pose->y;
112
      g_goal.theta = g_pose->theta;
113
      printGoal();
114
   }
115

  
116
   if (g_state == FORWARD) {
117
      forward(vel_pub);
118
   } else if (g_state == STOP_FORWARD) {
119
      stopForward(vel_pub);
120
   } else if (g_state == TURN) {
121
      turn(vel_pub);
122
   } else if (g_state == STOP_TURN) {
123
      stopTurn(vel_pub);
124
   }
146 125
}
147 126

  
148 127
int main(int argc, char** argv)
149 128
{
150
  ros::init(argc, argv, "draw_square");
151
  ros::NodeHandle nh;
152
  ros::Subscriber pose_sub = nh.subscribe("turtle1/pose", 1, poseCallback);
153
  ros::Publisher vel_pub = nh.advertise<turtlesim::Velocity>("turtle1/command_velocity", 1);
154
  ros::ServiceClient reset = nh.serviceClient<std_srvs::Empty>("reset");
155
  ros::Timer timer = nh.createTimer(ros::Duration(0.016), boost::bind(timerCallback, _1, vel_pub));
156

  
157
  std_srvs::Empty empty;
158
  reset.call(empty);
159

  
160
  ros::spin();
129
   ros::init(argc, argv, "draw_square");
130
   ros::NodeHandle nh;
131
   ros::Subscriber pose_sub = nh.subscribe("turtle1/pose", 1, poseCallback);
132
   ros::Publisher vel_pub =
133
      nh.advertise<turtlesim::Velocity>("turtle1/command_velocity", 1);
134
   ros::ServiceClient reset = nh.serviceClient<std_srvs::Empty>("reset");
135
   ros::Timer timer = nh.createTimer(ros::Duration(0.016),
136
                                     boost::bind(timerCallback, _1, vel_pub));
137

  
138
   std_srvs::Empty empty;
139
   reset.call(empty);
140

  
141
   ros::spin();
161 142
}
buggysim/tutorials/mimic.cpp
5 5
class Mimic
6 6
{
7 7
public:
8
  Mimic();
8
   Mimic();
9 9

  
10 10
private:
11
  void poseCallback(const turtlesim::PoseConstPtr& pose);
11
   void poseCallback(const turtlesim::PoseConstPtr& pose);
12 12

  
13
  ros::Publisher vel_pub_;
14
  ros::Subscriber pose_sub_;
13
   ros::Publisher vel_pub_;
14
   ros::Subscriber pose_sub_;
15 15
};
16 16

  
17 17
Mimic::Mimic()
18 18
{
19
  ros::NodeHandle input_nh("input");
20
  ros::NodeHandle output_nh("output");
21
  vel_pub_ = output_nh.advertise<turtlesim::Velocity>("command_velocity", 1);
22
  pose_sub_ = input_nh.subscribe<turtlesim::Pose>("pose", 1, &Mimic::poseCallback, this);
19
   ros::NodeHandle input_nh("input");
20
   ros::NodeHandle output_nh("output");
21
   vel_pub_ = output_nh.advertise<turtlesim::Velocity>("command_velocity", 1);
22
   pose_sub_ = input_nh.subscribe<turtlesim::Pose>("pose", 1, &Mimic::poseCallback,
23
               this);
23 24
}
24 25

  
25 26
void Mimic::poseCallback(const turtlesim::PoseConstPtr& pose)
26 27
{
27
  turtlesim::Velocity vel;
28
  vel.angular = pose->angular_velocity;
29
  vel.linear = pose->linear_velocity;
30
  vel_pub_.publish(vel);
28
   turtlesim::Velocity vel;
29
   vel.angular = pose->angular_velocity;
30
   vel.linear = pose->linear_velocity;
31
   vel_pub_.publish(vel);
31 32
}
32 33

  
33 34
int main(int argc, char** argv)
34 35
{
35
  ros::init(argc, argv, "turtle_mimic");
36
  Mimic mimic;
36
   ros::init(argc, argv, "turtle_mimic");
37
   Mimic mimic;
37 38

  
38
  ros::spin();
39
   ros::spin();
39 40
}
40 41

  
buggysim/tutorials/teleop_turtle_key.cpp
1 1
/**
2
 * Simple C++ Publisher; 
3
 *   Publish keystrokes to the 	
2
 * Simple C++ Publisher;
3
 *   Publish keystrokes to the
4 4
 *
5 5
 */
6 6
#include <ros/ros.h>
......
9 9
#include <termios.h>
10 10
#include <stdio.h>
11 11

  
12
#define KEYCODE_R 0x43 
12
#define KEYCODE_R 0x43
13 13
#define KEYCODE_L 0x44
14 14
#define KEYCODE_U 0x41
15 15
#define KEYCODE_D 0x42
......
18 18
class TeleopTurtle
19 19
{
20 20
public:
21
  TeleopTurtle();
22
  void keyLoop();
21
   TeleopTurtle();
22
   void keyLoop();
23 23

  
24 24
private:
25 25

  
26
  
27
  ros::NodeHandle nh_;
28
  double linear_, angular_, l_scale_, a_scale_;
29
  ros::Publisher vel_pub_;
30
  
26

  
27
   ros::NodeHandle nh_;
28
   double linear_, angular_, l_scale_, a_scale_;
29
   ros::Publisher vel_pub_;
30

  
31 31
};
32 32

  
33 33
TeleopTurtle::TeleopTurtle():
34
  linear_(0),
35
  angular_(0),
36
  l_scale_(2.0),
37
  a_scale_(2.0)
34
   linear_(0),
35
   angular_(0),
36
   l_scale_(2.0),
37
   a_scale_(2.0)
38 38
{
39
  nh_.param("scale_angular", a_scale_, a_scale_);
40
  nh_.param("scale_linear", l_scale_, l_scale_);
39
   nh_.param("scale_angular", a_scale_, a_scale_);
40
   nh_.param("scale_linear", l_scale_, l_scale_);
41 41

  
42
  vel_pub_ = nh_.advertise<turtlesim::Velocity>("turtle1/command_velocity", 1);
42
   vel_pub_ = nh_.advertise<turtlesim::Velocity>("turtle1/command_velocity", 1);
43 43
}
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff