Project

General

Profile

Revision 907874ca

ID907874cada2a7afdaa49349cfa02c8bfb7364d39
Parent 1efba872
Child d7757f92

Added by Tahm over 10 years ago

Lost to C++; I seem to be unable to template-pattern buggy.cpp into AbstractBuggy/BuggyImpl, due to issues with protected member variables changing on me. I'm not sure what this was, and I'll try it again some time. Maybe.

View differences:

buggysim/src/buggy.cpp
39 39
namespace buggysim
40 40
{
41 41

  
42
   AbstractBuggy::AbstractBuggy(const ros::NodeHandle& nh,
43
                                const QImage& turtle_image,
44
                                const QPointF& pos,
45
                                float orient)
46
      : nh_(nh)
47
      , turtle_image_(turtle_image)
48
      , pos_(pos)
49
      , orient_(orient)
50
      //, lin_vel_(2.0)
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)
51 48
      //, ang_vel_(0.0)
52
      //, turnAngle_(0.0)
53
      , pen_on_(true)
54
      , pen_(QColor(DEFAULT_PEN_R, DEFAULT_PEN_G, DEFAULT_PEN_B))
55
   {
56
      pen_.setWidth(3);
57
      ROS_INFO("Namespace in abstract buggy: %s", nh.getNamespace().data());
58
      ROS_INFO("Namespace in abstract buggy, stored: %s", nh_.getNamespace().data());
59
      //angle_sub_ = nh_.subscribe
60
      //             ("command_turnAngle", 1, &AbstractBuggy::turnAngleCallback, this);
61
      //pose_pub_ = nh_.advertise<buggymsgs::Pose>("pose", 1);
62

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

  
71

  
72
      meter_ = turtle_image_.height();
73
      rotateImage();
74
   }
75

  
76
   // This is a virtual method, to be implemented by the subclass
77
   /*void AbstractBuggy::turnAngleCallback(const buggymsgs::DirectionConstPtr& dir)
78
   {
79
      last_command_time_ = ros::WallTime::now();
80
      turnAngle_ = dir->turnAngle;
81
      //lin_vel_ = vel->linear;
82
      //ang_vel_ = vel->angular;
83
   }*/
84

  
85
   bool AbstractBuggy::setPenCallback(buggysim::SetPen::Request& req,
86
                               buggysim::SetPen::Response&)
87
   {
88
      pen_on_ = !req.off;
89
      if (req.off) {
90
         return true;
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;
91 87
      }
92 88

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

  
98
      pen_ = pen;
99
      return true;
100
   }
101

  
102
   bool AbstractBuggy::teleportRelativeCallback(buggysim::TeleportRelative::Request& req,
103
                                         buggysim::TeleportRelative::Response&)
104
   {
105
      teleport_requests_.push_back(TeleportRequest(0, 0, req.angular, req.linear,
106
                                   true));
107
      return true;
108
   }
109

  
110
   bool AbstractBuggy::teleportAbsoluteCallback(buggysim::TeleportAbsolute::Request& req,
111
                                         buggysim::TeleportAbsolute::Response&)
112
   {
113
      teleport_requests_.push_back(TeleportRequest(req.x, req.y, req.theta, 0,
114
                                   false));
115
      return true;
116
   }
117

  
118
   void AbstractBuggy::rotateImage()
119
   {
120
      QTransform transform;
121
      transform.rotate(-orient_ * 180.0 / PI + 90.0);
122
      turtle_rotated_image_ = turtle_image_.transformed(transform);
123
   }
124

  
125
   bool AbstractBuggy::update(double dt, QPainter& path_painter, const QImage& path_image,
126
                       qreal canvas_width, qreal canvas_height)
127
   {
128

  
129
       return false;
130

  
131
   }
132

  
133
   void AbstractBuggy::paint(QPainter& painter)
134
   {
135
      QPointF p = pos_ * meter_;
136
      p.rx() -= 0.5 * turtle_rotated_image_.width();
137
      p.ry() -= 0.5 * turtle_rotated_image_.height();
138
      painter.drawImage(p, turtle_rotated_image_);
139
   }
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
  }
140 248

  
141 249
}

Also available in: Unified diff