turtle_frame.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2009, Willow Garage, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * * Neither the name of the Willow Garage, Inc. nor the names of its
14  * contributors may be used to endorse or promote products derived from
15  * this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #include "turtlesim/turtle_frame.h"
31 
32 #include <QPointF>
33 
34 #include <ros/package.h>
35 #include <cstdlib>
36 #include <ctime>
37 
38 #define DEFAULT_BG_R 0x45
39 #define DEFAULT_BG_G 0x56
40 #define DEFAULT_BG_B 0xff
41 
42 namespace turtlesim
43 {
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 , private_nh_("~")
52 {
53  setFixedSize(500, 500);
54  setWindowTitle("TurtleSim");
55 
56  srand(time(NULL));
57 
58  update_timer_ = new QTimer(this);
59  update_timer_->setInterval(16);
60  update_timer_->start();
61 
62  connect(update_timer_, SIGNAL(timeout()), this, SLOT(onUpdate()));
63 
64  if (!private_nh_.hasParam("background_r"))
65  {
66  private_nh_.setParam("background_r", DEFAULT_BG_R);
67  }
68  if (!private_nh_.hasParam("background_g"))
69  {
70  private_nh_.setParam("background_g", DEFAULT_BG_G);
71  }
72  if (!private_nh_.hasParam("background_b"))
73  {
74  private_nh_.setParam("background_b", DEFAULT_BG_B);
75  }
76 
77  QVector<QString> turtles;
78  turtles.append("box-turtle.png");
79  turtles.append("robot-turtle.png");
80  turtles.append("sea-turtle.png");
81  turtles.append("diamondback.png");
82  turtles.append("electric.png");
83  turtles.append("fuerte.png");
84  turtles.append("groovy.png");
85  turtles.append("hydro.svg");
86  turtles.append("indigo.svg");
87  turtles.append("jade.png");
88  turtles.append("kinetic.png");
89  turtles.append("lunar.png");
90  turtles.append("melodic.png");
91  turtles.append("noetic.png");
92 
93  QString images_path = (ros::package::getPath("turtlesim") + "/images/").c_str();
94  for (int i = 0; i < turtles.size(); ++i)
95  {
96  QImage img;
97  img.load(images_path + turtles[i]);
98  turtle_images_.append(img);
99  }
100 
101  meter_ = turtle_images_[0].height();
102 
103  clear();
104 
109 
110  ROS_INFO("Starting turtlesim with node name %s", ros::this_node::getName().c_str()) ;
111 
112  width_in_meters_ = (width() - 1) / meter_;
113  height_in_meters_ = (height() - 1) / meter_;
114  spawnTurtle("", width_in_meters_ / 2.0, height_in_meters_ / 2.0, 0);
115 
116  // spawn all available turtle types
117  if(false)
118  {
119  for(int index = 0; index < turtles.size(); ++index)
120  {
121  QString name = turtles[index];
122  name = name.split(".").first();
123  name.replace(QString("-"), QString(""));
124  spawnTurtle(name.toStdString(), 1.0 + 1.5 * (index % 7), 1.0 + 1.5 * (index / 7), PI / 2.0, index);
125  }
126  }
127 }
128 
130 {
131  delete update_timer_;
132 }
133 
134 bool TurtleFrame::spawnCallback(turtlesim::Spawn::Request& req, turtlesim::Spawn::Response& res)
135 {
136  std::string name = spawnTurtle(req.name, req.x, req.y, req.theta);
137  if (name.empty())
138  {
139  ROS_ERROR("A turtled named [%s] already exists", req.name.c_str());
140  return false;
141  }
142 
143  res.name = name;
144 
145  return true;
146 }
147 
148 bool TurtleFrame::killCallback(turtlesim::Kill::Request& req, turtlesim::Kill::Response&)
149 {
150  M_Turtle::iterator it = turtles_.find(req.name);
151  if (it == turtles_.end())
152  {
153  ROS_ERROR("Tried to kill turtle [%s], which does not exist", req.name.c_str());
154  return false;
155  }
156 
157  turtles_.erase(it);
158  update();
159 
160  return true;
161 }
162 
163 bool TurtleFrame::hasTurtle(const std::string& name)
164 {
165  return turtles_.find(name) != turtles_.end();
166 }
167 
168 std::string TurtleFrame::spawnTurtle(const std::string& name, float x, float y, float angle)
169 {
170  return spawnTurtle(name, x, y, angle, rand() % turtle_images_.size());
171 }
172 
173 std::string TurtleFrame::spawnTurtle(const std::string& name, float x, float y, float angle, size_t index)
174 {
175  std::string real_name = name;
176  if (real_name.empty())
177  {
178  do
179  {
180  std::stringstream ss;
181  ss << "turtle" << ++id_counter_;
182  real_name = ss.str();
183  } while (hasTurtle(real_name));
184  }
185  else
186  {
187  if (hasTurtle(real_name))
188  {
189  return "";
190  }
191  }
192 
193  TurtlePtr t(new Turtle(ros::NodeHandle(real_name), turtle_images_[index], QPointF(x, height_in_meters_ - y), angle));
194  turtles_[real_name] = t;
195  update();
196 
197  ROS_INFO("Spawning turtle [%s] at x=[%f], y=[%f], theta=[%f]", real_name.c_str(), x, y, angle);
198 
199  return real_name;
200 }
201 
203 {
204  int r = DEFAULT_BG_R;
205  int g = DEFAULT_BG_G;
206  int b = DEFAULT_BG_B;
207 
208  private_nh_.param("background_r", r, r);
209  private_nh_.param("background_g", g, g);
210  private_nh_.param("background_b", b, b);
211 
212  path_image_.fill(qRgb(r, g, b));
213  update();
214 }
215 
217 {
218  ros::spinOnce();
219 
220  updateTurtles();
221 
222  if (!ros::ok())
223  {
224  close();
225  }
226 }
227 
228 void TurtleFrame::paintEvent(QPaintEvent*)
229 {
230  QPainter painter(this);
231 
232  painter.drawImage(QPoint(0, 0), path_image_);
233 
234  M_Turtle::iterator it = turtles_.begin();
235  M_Turtle::iterator end = turtles_.end();
236  for (; it != end; ++it)
237  {
238  it->second->paint(painter);
239  }
240 }
241 
243 {
245  {
247  return;
248  }
249 
250  bool modified = false;
251  M_Turtle::iterator it = turtles_.begin();
252  M_Turtle::iterator end = turtles_.end();
253  for (; it != end; ++it)
254  {
255  modified |= it->second->update(0.001 * update_timer_->interval(), path_painter_, path_image_, width_in_meters_, height_in_meters_);
256  }
257  if (modified)
258  {
259  update();
260  }
261 
262  ++frame_count_;
263 }
264 
265 
266 bool TurtleFrame::clearCallback(std_srvs::Empty::Request&, std_srvs::Empty::Response&)
267 {
268  ROS_INFO("Clearing turtlesim.");
269  clear();
270  return true;
271 }
272 
273 bool TurtleFrame::resetCallback(std_srvs::Empty::Request&, std_srvs::Empty::Response&)
274 {
275  ROS_INFO("Resetting turtlesim.");
276  turtles_.clear();
277  id_counter_ = 0;
278  spawnTurtle("", width_in_meters_ / 2.0, height_in_meters_ / 2.0, 0);
279  clear();
280  return true;
281 }
282 
283 }
ros::NodeHandle::setParam
void setParam(const std::string &key, bool b) const
ros::package::getPath
ROSLIB_DECL std::string getPath(const std::string &package_name)
turtlesim::TurtleFrame::TurtleFrame
TurtleFrame(QWidget *parent=0, Qt::WindowFlags f=0)
Definition: turtle_frame.cpp:45
boost::shared_ptr
turtlesim
Definition: turtle.h:53
turtle_frame.h
turtlesim::TurtleFrame::~TurtleFrame
~TurtleFrame()
Definition: turtle_frame.cpp:129
turtlesim::TurtleFrame::killCallback
bool killCallback(turtlesim::Kill::Request &, turtlesim::Kill::Response &)
Definition: turtle_frame.cpp:148
turtlesim::TurtleFrame::id_counter_
uint32_t id_counter_
Definition: turtle_frame.h:95
ros::spinOnce
ROSCPP_DECL void spinOnce()
ros::NodeHandle::advertiseService
ServiceServer advertiseService(AdvertiseServiceOptions &ops)
turtlesim::TurtleFrame::update_timer_
QTimer * update_timer_
Definition: turtle_frame.h:80
turtlesim::TurtleFrame::reset_srv_
ros::ServiceServer reset_srv_
Definition: turtle_frame.h:89
turtlesim::TurtleFrame::spawnTurtle
std::string spawnTurtle(const std::string &name, float x, float y, float angle)
Definition: turtle_frame.cpp:168
turtlesim::TurtleFrame::spawnCallback
bool spawnCallback(turtlesim::Spawn::Request &, turtlesim::Spawn::Response &)
Definition: turtle_frame.cpp:134
turtlesim::TurtleFrame::path_image_
QImage path_image_
Definition: turtle_frame.h:81
ros::ok
ROSCPP_DECL bool ok()
f
f
turtlesim::TurtleFrame::last_turtle_update_
ros::WallTime last_turtle_update_
Definition: turtle_frame.h:86
turtlesim::TurtleFrame::spawn_srv_
ros::ServiceServer spawn_srv_
Definition: turtle_frame.h:90
turtlesim::TurtleFrame::clearCallback
bool clearCallback(std_srvs::Empty::Request &, std_srvs::Empty::Response &)
Definition: turtle_frame.cpp:266
turtlesim::TurtleFrame::path_painter_
QPainter path_painter_
Definition: turtle_frame.h:82
turtlesim::TurtleFrame::clear
void clear()
Definition: turtle_frame.cpp:202
update
void update(const std::string &key, const XmlRpc::XmlRpcValue &v)
turtlesim::TurtleFrame::width_in_meters_
float width_in_meters_
Definition: turtle_frame.h:100
TimeBase< WallTime, WallDuration >::isZero
bool isZero() const
ros::WallTime::now
static WallTime now()
DEFAULT_BG_R
#define DEFAULT_BG_R
Definition: turtle_frame.cpp:38
turtlesim::TurtleFrame::onUpdate
void onUpdate()
Definition: turtle_frame.cpp:216
ros::NodeHandle::hasParam
bool hasParam(const std::string &key) const
turtlesim::TurtleFrame::kill_srv_
ros::ServiceServer kill_srv_
Definition: turtle_frame.h:91
package.h
ros::this_node::getName
const ROSCPP_DECL std::string & getName()
turtlesim::TurtleFrame::frame_count_
uint64_t frame_count_
Definition: turtle_frame.h:84
turtlesim::TurtleFrame::updateTurtles
void updateTurtles()
Definition: turtle_frame.cpp:242
DEFAULT_BG_B
#define DEFAULT_BG_B
Definition: turtle_frame.cpp:40
turtlesim::TurtleFrame::height_in_meters_
float height_in_meters_
Definition: turtle_frame.h:101
ROS_ERROR
#define ROS_ERROR(...)
turtlesim::TurtleFrame::turtles_
M_Turtle turtles_
Definition: turtle_frame.h:94
turtlesim::TurtleFrame::paintEvent
void paintEvent(QPaintEvent *event)
Definition: turtle_frame.cpp:228
PI
#define PI
Definition: turtle.h:51
ros::NodeHandle::param
T param(const std::string &param_name, const T &default_val) const
turtlesim::Turtle
Definition: turtle.h:56
turtlesim::TurtleFrame::clear_srv_
ros::ServiceServer clear_srv_
Definition: turtle_frame.h:88
turtlesim::TurtleFrame::turtle_images_
QVector< QImage > turtle_images_
Definition: turtle_frame.h:97
turtlesim::TurtleFrame::resetCallback
bool resetCallback(std_srvs::Empty::Request &, std_srvs::Empty::Response &)
Definition: turtle_frame.cpp:273
turtlesim::TurtleFrame::nh_
ros::NodeHandle nh_
Definition: turtle_frame.h:78
ROS_INFO
#define ROS_INFO(...)
turtlesim::TurtleFrame::meter_
float meter_
Definition: turtle_frame.h:99
turtlesim::TurtleFrame::private_nh_
ros::NodeHandle private_nh_
Definition: turtle_frame.h:79
turtlesim::TurtleFrame::hasTurtle
bool hasTurtle(const std::string &name)
Definition: turtle_frame.cpp:163
ros::NodeHandle
DEFAULT_BG_G
#define DEFAULT_BG_G
Definition: turtle_frame.cpp:39


turtlesim
Author(s): Josh Faust, Dirk Thomas
autogenerated on Sat Apr 12 2025 02:28:03