Revision 144137a1
ID | 144137a12c1437f71d49b144279823dc836cb14b |
Got motor control working with scoutsim
Behaviors can now use the MotorControl class to change the speed of the motors in the simulator. The simulator correctly handles the command.
At the moment, the set_motors command is limited to 'scout1'. We should look into prefixes to specify which scout (scout1, scout2, etc) each behavior should command.
Also changed alex_behavior to be a good demonstration of the motors.
scout/libscout/src/MotorControl.cpp | ||
---|---|---|
47 | 47 |
: node(libscout_node) |
48 | 48 |
{ |
49 | 49 |
set_motors_pub = |
50 |
node.advertise<motors::set_motors>("set_motors", QUEUE_SIZE); |
|
50 |
node.advertise<motors::set_motors>("scout1/set_motors", QUEUE_SIZE);
|
|
51 | 51 |
query_motors_client = |
52 | 52 |
node.serviceClient<motors::query_motors>("query_motors"); |
53 | 53 |
} |
scout/libscout/src/alex_behavior.cpp | ||
---|---|---|
46 | 46 |
ros::NodeHandle node; |
47 | 47 |
|
48 | 48 |
MotorControl motors(node); |
49 |
//ButtonControl buttons(node); |
|
49 | 50 |
|
50 | 51 |
ros::Rate loop_rate(10); |
51 | 52 |
|
52 | 53 |
while(ros::ok()) |
53 | 54 |
{ |
54 |
motors.set_sides(20, 80); |
|
55 |
motors.set_sides(20, 80, MOTOR_ABSOLUTE);
|
|
55 | 56 |
|
56 | 57 |
ros::spinOnce(); |
57 | 58 |
loop_rate.sleep(); |
scout/scoutsim/CMakeLists.txt | ||
---|---|---|
32 | 32 |
rosbuild_link_boost(scoutsim_node thread) |
33 | 33 |
target_link_libraries(scoutsim_node ${wxWidgets_LIBRARIES}) |
34 | 34 |
|
35 |
|
|
36 |
include($ENV{ROS_ROOT}/core/rosbuild/FindPkgConfig.cmake) |
|
37 |
include_directories(${MOTORS_INCLUDE_DIRS}) |
|
38 |
link_directories(${MOTORS_LIBRARY_DIRS}) |
|
39 |
target_link_libraries(scoutsim_node ${MOTORS_LIBRARIES}) |
|
40 |
|
|
41 |
target_link_libraries(scoutsim_node motors) |
|
42 |
|
|
43 | 35 |
# @TODO are these useful or necessary? Determine; add as needed |
44 | 36 |
#rosbuild_add_executable(turtle_teleop_key tutorials/teleop_turtle_key.cpp) |
45 | 37 |
#rosbuild_add_executable(draw_square tutorials/draw_square.cpp) |
scout/scoutsim/msg/Velocity.msg | ||
---|---|---|
1 | 1 |
float32 linear |
2 |
float32 angular |
|
2 |
float32 angular |
scout/scoutsim/src/scout.cpp | ||
---|---|---|
24 | 24 |
const wxImage& scout_image, |
25 | 25 |
const Vector2& pos, |
26 | 26 |
float orient) |
27 |
: n_(nh)
|
|
28 |
, scout_image_(scout_image)
|
|
29 |
, pos_(pos)
|
|
30 |
, orient_(orient)
|
|
31 |
, lin_vel_(0.0)
|
|
32 |
, ang_vel_(0.0)
|
|
33 |
, pen_on_(true)
|
|
34 |
, pen_(wxColour(DEFAULT_PEN_R, DEFAULT_PEN_G, DEFAULT_PEN_B))
|
|
27 |
: node (nh)
|
|
28 |
, scout_image(scout_image) |
|
29 |
, pos(pos) |
|
30 |
, orient(orient) |
|
31 |
, lin_vel(0.0) |
|
32 |
, ang_vel(0.0) |
|
33 |
, pen_on(true) |
|
34 |
, pen(wxColour(DEFAULT_PEN_R, DEFAULT_PEN_G, DEFAULT_PEN_B)) |
|
35 | 35 |
{ |
36 |
pen_.SetWidth(3); |
|
37 |
scout_ = wxBitmap(scout_image_); |
|
38 |
|
|
39 |
motors_sub_ = n_.subscribe("set_motors", 1, &Scout::setMotors, this); |
|
40 |
|
|
41 |
/// @TODO take this out! |
|
42 |
velocity_sub_ = |
|
43 |
n_.subscribe("command_velocity", |
|
44 |
1, |
|
45 |
&Scout::velocityCallback, this); |
|
46 |
pose_pub_ = n_.advertise<Pose>("pose", 1); |
|
47 |
color_pub_ = n_.advertise<Color>("color_sensor", 1); |
|
48 |
set_pen_srv_ = n_.advertiseService("set_pen", |
|
36 |
pen.SetWidth(3); |
|
37 |
scout = wxBitmap(scout_image); |
|
38 |
|
|
39 |
motors_sub = node.subscribe("set_motors", 1, &Scout::setMotors, this); |
|
40 |
|
|
41 |
pose_pub = node.advertise<Pose>("pose", 1); |
|
42 |
color_pub = node.advertise<Color>("color_sensor", 1); |
|
43 |
set_pen_srv = node.advertiseService("set_pen", |
|
49 | 44 |
&Scout::setPenCallback, |
50 | 45 |
this); |
51 |
teleport_relative_srv_ =
|
|
52 |
n_.advertiseService("teleport_relative",
|
|
46 |
teleport_relative_srv = |
|
47 |
node.advertiseService("teleport_relative",
|
|
53 | 48 |
&Scout::teleportRelativeCallback, |
54 | 49 |
this); |
55 |
teleport_absolute_srv_ =
|
|
56 |
n_.advertiseService("teleport_absolute",
|
|
50 |
teleport_absolute_srv = |
|
51 |
node.advertiseService("teleport_absolute",
|
|
57 | 52 |
&Scout::teleportAbsoluteCallback, |
58 | 53 |
this); |
59 | 54 |
|
60 |
meter_ = scout_.GetHeight();
|
|
55 |
meter = scout.GetHeight();
|
|
61 | 56 |
} |
62 | 57 |
|
63 | 58 |
/** |
... | ... | |
66 | 61 |
*/ |
67 | 62 |
void Scout::setMotors(const motors::set_motors::ConstPtr& msg) |
68 | 63 |
{ |
69 |
last_command_time_ = ros::WallTime::now();
|
|
64 |
last_command_time = ros::WallTime::now(); |
|
70 | 65 |
|
71 | 66 |
if(msg->fl_set) |
72 | 67 |
{ |
73 |
motor_fl_speed_ = msg->fl_speed;
|
|
68 |
motor_fl_speed = msg->fl_speed; |
|
74 | 69 |
} |
75 | 70 |
if(msg->fr_set) |
76 | 71 |
{ |
77 |
motor_fr_speed_ = msg->fr_speed;
|
|
72 |
motor_fr_speed = msg->fr_speed; |
|
78 | 73 |
} |
79 | 74 |
if(msg->bl_set) |
80 | 75 |
{ |
81 |
motor_bl_speed_ = msg->bl_speed;
|
|
76 |
motor_bl_speed = msg->bl_speed; |
|
82 | 77 |
} |
83 | 78 |
if(msg->br_set) |
84 | 79 |
{ |
85 |
motor_br_speed_ = msg->br_speed;
|
|
80 |
motor_br_speed = msg->br_speed; |
|
86 | 81 |
} |
87 | 82 |
|
88 |
float l_speed = (float (motor_fl_speed_ + motor_bl_speed_)) / 2; |
|
89 |
float r_speed = (float (motor_fr_speed_ + motor_br_speed_)) / 2; |
|
90 |
|
|
91 |
/// @TODO Change this! |
|
92 |
lin_vel_ = (l_speed + r_speed) / 2; |
|
93 |
ang_vel_ = r_speed - l_speed; |
|
83 |
// Assume that the two motors on the same side will be set to |
|
84 |
// roughly the same speed. Does not account for slip conditions |
|
85 |
// when they are set to different speeds. |
|
86 |
float l_speed = (float (motor_fl_speed + motor_bl_speed)) / 2; |
|
87 |
float r_speed = (float (motor_fr_speed + motor_br_speed)) / 2; |
|
94 | 88 |
|
95 |
} |
|
96 |
|
|
97 |
void Scout::velocityCallback(const VelocityConstPtr& vel) |
|
98 |
{ |
|
99 |
last_command_time_ = ros::WallTime::now(); |
|
100 |
lin_vel_ = vel->linear; |
|
101 |
ang_vel_ = vel->angular; |
|
89 |
// Set the linear and angular speeds |
|
90 |
lin_vel = SPEED_SCALE_FACTOR * (l_speed + r_speed) / 2; |
|
91 |
ang_vel = SPEED_SCALE_FACTOR * (r_speed - l_speed); |
|
102 | 92 |
} |
103 | 93 |
|
104 | 94 |
bool Scout::setPenCallback(scoutsim::SetPen::Request& req, |
105 | 95 |
scoutsim::SetPen::Response&) |
106 | 96 |
{ |
107 |
pen_on_ = !req.off;
|
|
97 |
pen_on = !req.off; |
|
108 | 98 |
if (req.off) |
109 | 99 |
{ |
110 | 100 |
return true; |
... | ... | |
116 | 106 |
pen.SetWidth(req.width); |
117 | 107 |
} |
118 | 108 |
|
119 |
pen_ = pen;
|
|
109 |
pen = pen; |
|
120 | 110 |
return true; |
121 | 111 |
} |
122 | 112 |
|
113 |
/// @TODO remove |
|
123 | 114 |
bool Scout::teleportRelativeCallback(scoutsim::TeleportRelative::Request& req, |
124 | 115 |
scoutsim::TeleportRelative::Response&) |
125 | 116 |
{ |
126 |
teleport_requests_.push_back(TeleportRequest(0,
|
|
117 |
teleport_requests.push_back(TeleportRequest(0, |
|
127 | 118 |
0, |
128 | 119 |
req.angular, |
129 | 120 |
req.linear, |
... | ... | |
131 | 122 |
return true; |
132 | 123 |
} |
133 | 124 |
|
125 |
/// @TODO remove |
|
134 | 126 |
bool Scout::teleportAbsoluteCallback(scoutsim::TeleportAbsolute::Request& req, |
135 | 127 |
scoutsim::TeleportAbsolute::Response&) |
136 | 128 |
{ |
137 |
teleport_requests_.push_back(TeleportRequest(req.x,
|
|
129 |
teleport_requests.push_back(TeleportRequest(req.x, |
|
138 | 130 |
req.y, |
139 | 131 |
req.theta, |
140 | 132 |
0, |
... | ... | |
147 | 139 |
float canvas_width, float canvas_height) |
148 | 140 |
{ |
149 | 141 |
// first process any teleportation requests, in order |
150 |
V_TeleportRequest::iterator it = teleport_requests_.begin();
|
|
151 |
V_TeleportRequest::iterator end = teleport_requests_.end();
|
|
142 |
V_TeleportRequest::iterator it = teleport_requests.begin(); |
|
143 |
V_TeleportRequest::iterator end = teleport_requests.end(); |
|
152 | 144 |
for (; it != end; ++it) |
153 | 145 |
{ |
154 | 146 |
const TeleportRequest& req = *it; |
155 | 147 |
|
156 |
Vector2 old_pos = pos_;
|
|
148 |
Vector2 old_pos = pos; |
|
157 | 149 |
if (req.relative) |
158 | 150 |
{ |
159 |
orient_ += req.theta;
|
|
160 |
pos_.x += sin(orient_ + PI/2.0) * req.linear;
|
|
161 |
pos_.y += cos(orient_ + PI/2.0) * req.linear;
|
|
151 |
orient += req.theta; |
|
152 |
pos.x += sin(orient + PI/2.0) * req.linear;
|
|
153 |
pos.y += cos(orient + PI/2.0) * req.linear;
|
|
162 | 154 |
} |
163 | 155 |
else |
164 | 156 |
{ |
165 |
pos_.x = req.pos.x;
|
|
166 |
pos_.y = std::max(0.0f, canvas_height - req.pos.y);
|
|
167 |
orient_ = req.theta;
|
|
157 |
pos.x = req.pos.x; |
|
158 |
pos.y = std::max(0.0f, canvas_height - req.pos.y); |
|
159 |
orient = req.theta; |
|
168 | 160 |
} |
169 | 161 |
|
170 |
path_dc.SetPen(pen_);
|
|
171 |
path_dc.DrawLine(pos_.x * meter_, pos_.y * meter_,
|
|
172 |
old_pos.x * meter_, old_pos.y * meter_);
|
|
162 |
path_dc.SetPen(pen); |
|
163 |
path_dc.DrawLine(pos.x * meter, pos.y * meter,
|
|
164 |
old_pos.x * meter, old_pos.y * meter);
|
|
173 | 165 |
} |
174 | 166 |
|
175 |
teleport_requests_.clear();
|
|
167 |
teleport_requests.clear(); |
|
176 | 168 |
|
177 |
if (ros::WallTime::now() - last_command_time_ > ros::WallDuration(1.0))
|
|
169 |
if (ros::WallTime::now() - last_command_time > ros::WallDuration(1.0)) |
|
178 | 170 |
{ |
179 |
lin_vel_ = 0.0f;
|
|
180 |
ang_vel_ = 0.0f;
|
|
171 |
lin_vel = 0.0f; |
|
172 |
ang_vel = 0.0f; |
|
181 | 173 |
} |
182 | 174 |
|
183 |
Vector2 old_pos = pos_;
|
|
175 |
Vector2 old_pos = pos; |
|
184 | 176 |
|
185 |
orient_ = fmod(orient_ + ang_vel_ * dt, 2*PI);
|
|
186 |
pos_.x += sin(orient_ + PI/2.0) * lin_vel_ * dt;
|
|
187 |
pos_.y += cos(orient_ + PI/2.0) * lin_vel_ * dt;
|
|
177 |
orient = fmod(orient + ang_vel * dt, 2*PI);
|
|
178 |
pos.x += sin(orient + PI/2.0) * lin_vel * dt;
|
|
179 |
pos.y += cos(orient + PI/2.0) * lin_vel * dt;
|
|
188 | 180 |
|
189 | 181 |
// Clamp to screen size |
190 |
if (pos_.x < 0 || pos_.x >= canvas_width
|
|
191 |
|| pos_.y < 0 || pos_.y >= canvas_height)
|
|
182 |
if (pos.x < 0 || pos.x >= canvas_width
|
|
183 |
|| pos.y < 0 || pos.y >= canvas_height)
|
|
192 | 184 |
{ |
193 |
ROS_WARN("Oh no! I hit the wall! (Clamping from [x=%f, y=%f])", pos_.x, pos_.y);
|
|
185 |
ROS_WARN("Oh no! I hit the wall! (Clamping from [x=%f, y=%f])", pos.x, pos.y);
|
|
194 | 186 |
} |
195 | 187 |
|
196 |
pos_.x = std::min(std::max(pos_.x, 0.0f), canvas_width);
|
|
197 |
pos_.y = std::min(std::max(pos_.y, 0.0f), canvas_height);
|
|
188 |
pos.x = std::min(std::max(pos.x, 0.0f), canvas_width);
|
|
189 |
pos.y = std::min(std::max(pos.y, 0.0f), canvas_height);
|
|
198 | 190 |
|
199 |
int canvas_x = pos_.x * meter_;
|
|
200 |
int canvas_y = pos_.y * meter_;
|
|
191 |
int canvas_x = pos.x * meter;
|
|
192 |
int canvas_y = pos.y * meter;
|
|
201 | 193 |
|
202 | 194 |
{ |
203 | 195 |
wxImage rotated_image = |
204 |
scout_image_.Rotate(orient_ - PI/2.0,
|
|
205 |
wxPoint(scout_image_.GetWidth() / 2,
|
|
206 |
scout_image_.GetHeight() / 2),
|
|
196 |
scout_image.Rotate(orient - PI/2.0,
|
|
197 |
wxPoint(scout_image.GetWidth() / 2,
|
|
198 |
scout_image.GetHeight() / 2), |
|
207 | 199 |
false); |
208 | 200 |
|
209 | 201 |
for (int y = 0; y < rotated_image.GetHeight(); ++y) |
... | ... | |
219 | 211 |
} |
220 | 212 |
} |
221 | 213 |
|
222 |
scout_ = wxBitmap(rotated_image);
|
|
214 |
scout = wxBitmap(rotated_image); |
|
223 | 215 |
} |
224 | 216 |
|
225 | 217 |
Pose p; |
226 |
p.x = pos_.x;
|
|
227 |
p.y = canvas_height - pos_.y;
|
|
228 |
p.theta = orient_;
|
|
229 |
p.linear_velocity = lin_vel_;
|
|
230 |
p.angular_velocity = ang_vel_;
|
|
231 |
pose_pub_.publish(p);
|
|
218 |
p.x = pos.x; |
|
219 |
p.y = canvas_height - pos.y; |
|
220 |
p.theta = orient; |
|
221 |
p.linear_velocity = lin_vel; |
|
222 |
p.angular_velocity = ang_vel; |
|
223 |
pose_pub.publish(p); |
|
232 | 224 |
|
233 | 225 |
// Figure out (and publish) the color underneath the scout |
234 | 226 |
{ |
235 |
wxSize scout_size = wxSize(scout_.GetWidth(), scout_.GetHeight());
|
|
227 |
wxSize scout_size = wxSize(scout.GetWidth(), scout.GetHeight());
|
|
236 | 228 |
Color color; |
237 | 229 |
color.r = path_image.GetRed(canvas_x, canvas_y); |
238 | 230 |
color.g = path_image.GetGreen(canvas_x, canvas_y); |
239 | 231 |
color.b = path_image.GetBlue(canvas_x, canvas_y); |
240 |
color_pub_.publish(color);
|
|
232 |
color_pub.publish(color); |
|
241 | 233 |
} |
242 | 234 |
|
243 | 235 |
ROS_DEBUG("[%s]: pos_x: %f pos_y: %f theta: %f", |
244 |
n_.getNamespace().c_str(), pos_.x, pos_.y, orient_);
|
|
236 |
node.getNamespace().c_str(), pos.x, pos.y, orient);
|
|
245 | 237 |
|
246 |
if (pen_on_)
|
|
238 |
if (pen_on) |
|
247 | 239 |
{ |
248 |
if (pos_ != old_pos)
|
|
240 |
if (pos != old_pos) |
|
249 | 241 |
{ |
250 |
path_dc.SetPen(pen_);
|
|
251 |
path_dc.DrawLine(pos_.x * meter_, pos_.y * meter_,
|
|
252 |
old_pos.x * meter_, old_pos.y * meter_);
|
|
242 |
path_dc.SetPen(pen); |
|
243 |
path_dc.DrawLine(pos.x * meter, pos.y * meter,
|
|
244 |
old_pos.x * meter, old_pos.y * meter);
|
|
253 | 245 |
} |
254 | 246 |
} |
255 | 247 |
} |
256 | 248 |
|
257 | 249 |
void Scout::paint(wxDC& dc) |
258 | 250 |
{ |
259 |
wxSize scout_size = wxSize(scout_.GetWidth(), scout_.GetHeight());
|
|
260 |
dc.DrawBitmap(scout_, pos_.x * meter_ - (scout_size.GetWidth() / 2),
|
|
261 |
pos_.y * meter_ - (scout_size.GetHeight() / 2), true);
|
|
251 |
wxSize scout_size = wxSize(scout.GetWidth(), scout.GetHeight());
|
|
252 |
dc.DrawBitmap(scout, pos.x * meter - (scout_size.GetWidth() / 2),
|
|
253 |
pos.y * meter - (scout_size.GetHeight() / 2), true);
|
|
262 | 254 |
} |
263 | 255 |
|
264 | 256 |
} |
scout/scoutsim/src/scout.h | ||
---|---|---|
9 | 9 |
* @author Alex Zirbel |
10 | 10 |
*/ |
11 | 11 |
|
12 |
#ifndef SCOUTSIM_SCOUT_H
|
|
13 |
#define SCOUTSIM_SCOUT_H
|
|
12 |
#ifndef _SCOUTSIM_SCOUT_H_
|
|
13 |
#define _SCOUTSIM_SCOUT_H_
|
|
14 | 14 |
|
15 | 15 |
#include <ros/ros.h> |
16 | 16 |
#include <boost/shared_ptr.hpp> |
... | ... | |
18 | 18 |
#include <motors/set_motors.h> |
19 | 19 |
|
20 | 20 |
#include <scoutsim/Pose.h> |
21 |
#include <scoutsim/Velocity.h> |
|
22 | 21 |
#include <scoutsim/SetPen.h> |
23 | 22 |
#include <scoutsim/TeleportRelative.h> |
24 | 23 |
#include <scoutsim/TeleportAbsolute.h> |
... | ... | |
27 | 26 |
#include <wx/wx.h> |
28 | 27 |
|
29 | 28 |
#define PI 3.14159265 |
29 |
/// The scale factor so the speed of scout robots is reasonable for the sim |
|
30 |
#define SPEED_SCALE_FACTOR 0.05 |
|
30 | 31 |
|
31 | 32 |
namespace scoutsim |
32 | 33 |
{ |
... | ... | |
37 | 38 |
, y(0.0) |
38 | 39 |
{} |
39 | 40 |
|
40 |
Vector2(float _x, float _y)
|
|
41 |
: x(_x) |
|
42 |
, y(_y) |
|
41 |
Vector2(float new_x, float new_y)
|
|
42 |
: x(new_x)
|
|
43 |
, y(new_y)
|
|
43 | 44 |
{} |
44 | 45 |
|
45 | 46 |
bool operator==(const Vector2& rhs) |
... | ... | |
69 | 70 |
|
70 | 71 |
private: |
71 | 72 |
void setMotors(const motors::set_motors::ConstPtr& msg); |
72 |
void velocityCallback(const VelocityConstPtr& vel); |
|
73 | 73 |
bool setPenCallback(scoutsim::SetPen::Request&, |
74 | 74 |
scoutsim::SetPen::Response&); |
75 | 75 |
bool teleportRelativeCallback(scoutsim::TeleportRelative::Request&, |
... | ... | |
77 | 77 |
bool teleportAbsoluteCallback(scoutsim::TeleportAbsolute::Request&, |
78 | 78 |
scoutsim::TeleportAbsolute::Response&); |
79 | 79 |
|
80 |
ros::NodeHandle n_;
|
|
80 |
ros::NodeHandle node;
|
|
81 | 81 |
|
82 |
wxImage scout_image_;
|
|
83 |
wxBitmap scout_;
|
|
82 |
wxImage scout_image; |
|
83 |
wxBitmap scout; |
|
84 | 84 |
|
85 |
Vector2 pos_;
|
|
86 |
float orient_;
|
|
85 |
Vector2 pos; |
|
86 |
float orient; |
|
87 | 87 |
|
88 | 88 |
// Keep track of the last commanded speeds sent to the sim |
89 |
int motor_fl_speed_;
|
|
90 |
int motor_fr_speed_;
|
|
91 |
int motor_bl_speed_;
|
|
92 |
int motor_br_speed_;
|
|
89 |
int motor_fl_speed; |
|
90 |
int motor_fr_speed; |
|
91 |
int motor_bl_speed; |
|
92 |
int motor_br_speed; |
|
93 | 93 |
|
94 |
float lin_vel_;
|
|
95 |
float ang_vel_;
|
|
96 |
bool pen_on_;
|
|
97 |
wxPen pen_;
|
|
94 |
float lin_vel; |
|
95 |
float ang_vel; |
|
96 |
bool pen_on; |
|
97 |
wxPen pen; |
|
98 | 98 |
|
99 |
ros::Subscriber motors_sub_; |
|
100 |
ros::Subscriber velocity_sub_; |
|
101 |
ros::Publisher pose_pub_; |
|
102 |
ros::Publisher color_pub_; |
|
103 |
ros::ServiceServer set_pen_srv_; |
|
104 |
ros::ServiceServer teleport_relative_srv_; |
|
105 |
ros::ServiceServer teleport_absolute_srv_; |
|
99 |
ros::Subscriber motors_sub; |
|
100 |
ros::Publisher pose_pub; |
|
101 |
ros::Publisher color_pub; |
|
102 |
ros::ServiceServer set_pen_srv; |
|
103 |
ros::ServiceServer teleport_relative_srv; |
|
104 |
ros::ServiceServer teleport_absolute_srv; |
|
106 | 105 |
|
107 |
ros::WallTime last_command_time_;
|
|
106 |
ros::WallTime last_command_time; |
|
108 | 107 |
|
109 |
float meter_;
|
|
108 |
float meter; |
|
110 | 109 |
|
111 | 110 |
struct TeleportRequest |
112 | 111 |
{ |
113 |
TeleportRequest(float x, float y, float _theta, |
|
114 |
float _linear, bool _relative)
|
|
112 |
TeleportRequest(float x, float y, float new_theta,
|
|
113 |
float new_linear, bool new_relative)
|
|
115 | 114 |
: pos(x, y) |
116 |
, theta(_theta) |
|
117 |
, linear(_linear) |
|
118 |
, relative(_relative) |
|
115 |
, theta(new_theta)
|
|
116 |
, linear(new_linear)
|
|
117 |
, relative(new_relative)
|
|
119 | 118 |
{} |
120 | 119 |
|
121 | 120 |
Vector2 pos; |
... | ... | |
125 | 124 |
}; |
126 | 125 |
|
127 | 126 |
typedef std::vector<TeleportRequest> V_TeleportRequest; |
128 |
V_TeleportRequest teleport_requests_;
|
|
127 |
V_TeleportRequest teleport_requests; |
|
129 | 128 |
}; |
130 | 129 |
typedef boost::shared_ptr<Scout> ScoutPtr; |
131 | 130 |
|
scout/scoutsim/src/scoutsim.cpp | ||
---|---|---|
26 | 26 |
class ScoutApp : public wxApp |
27 | 27 |
{ |
28 | 28 |
public: |
29 |
char** local_argv_;
|
|
30 |
ros::NodeHandlePtr nh_;
|
|
29 |
char** local_argv; |
|
30 |
ros::NodeHandlePtr nh; |
|
31 | 31 |
|
32 | 32 |
ScoutApp() |
33 | 33 |
{ |
... | ... | |
43 | 43 |
#endif |
44 | 44 |
|
45 | 45 |
// create our own copy of argv, with regular char*s. |
46 |
local_argv_ = new char*[ argc ];
|
|
46 |
local_argv = new char*[ argc ]; |
|
47 | 47 |
for ( int i = 0; i < argc; ++i ) |
48 | 48 |
{ |
49 |
local_argv_[ i ] = strdup( wxString( argv[ i ] ).mb_str() );
|
|
49 |
local_argv[ i ] = strdup( wxString( argv[ i ] ).mb_str() ); |
|
50 | 50 |
} |
51 | 51 |
|
52 |
ros::init(argc, local_argv_, "scoutsim");
|
|
53 |
nh_.reset(new ros::NodeHandle);
|
|
52 |
ros::init(argc, local_argv, "scoutsim"); |
|
53 |
nh.reset(new ros::NodeHandle); |
|
54 | 54 |
|
55 | 55 |
wxInitAllImageHandlers(); |
56 | 56 |
|
... | ... | |
66 | 66 |
{ |
67 | 67 |
for ( int i = 0; i < argc; ++i ) |
68 | 68 |
{ |
69 |
free( local_argv_[ i ] );
|
|
69 |
free( local_argv[ i ] ); |
|
70 | 70 |
} |
71 |
delete [] local_argv_;
|
|
71 |
delete [] local_argv; |
|
72 | 72 |
|
73 | 73 |
return 0; |
74 | 74 |
} |
scout/scoutsim/src/sim_frame.cpp | ||
---|---|---|
26 | 26 |
SimFrame::SimFrame(wxWindow* parent) |
27 | 27 |
: wxFrame(parent, wxID_ANY, wxT("ScoutSim"), wxDefaultPosition, |
28 | 28 |
wxSize(500, 500), wxDEFAULT_FRAME_STYLE & ~wxRESIZE_BORDER) |
29 |
, frame_count_(0)
|
|
30 |
, id_counter_(0)
|
|
29 |
, frame_count(0) |
|
30 |
, id_counter(0) |
|
31 | 31 |
{ |
32 | 32 |
srand(time(NULL)); |
33 | 33 |
|
34 |
update_timer_ = new wxTimer(this);
|
|
35 |
update_timer_->Start(16);
|
|
34 |
update_timer = new wxTimer(this); |
|
35 |
update_timer->Start(16); |
|
36 | 36 |
|
37 |
Connect(update_timer_->GetId(), wxEVT_TIMER,
|
|
37 |
Connect(update_timer->GetId(), wxEVT_TIMER, |
|
38 | 38 |
wxTimerEventHandler(SimFrame::onUpdate), NULL, this); |
39 | 39 |
Connect(wxEVT_PAINT, wxPaintEventHandler(SimFrame::onPaint), |
40 | 40 |
NULL, this); |
41 | 41 |
|
42 |
nh_.setParam("background_r", DEFAULT_BG_R);
|
|
43 |
nh_.setParam("background_g", DEFAULT_BG_G);
|
|
44 |
nh_.setParam("background_b", DEFAULT_BG_B);
|
|
42 |
nh.setParam("background_r", DEFAULT_BG_R); |
|
43 |
nh.setParam("background_g", DEFAULT_BG_G); |
|
44 |
nh.setParam("background_b", DEFAULT_BG_B); |
|
45 | 45 |
|
46 | 46 |
std::string scouts[SCOUTSIM_NUM_SCOUTS] = |
47 | 47 |
{ |
... | ... | |
51 | 51 |
std::string images_path = ros::package::getPath("scoutsim")+"/images/"; |
52 | 52 |
for (size_t i = 0; i < SCOUTSIM_NUM_SCOUTS; ++i) |
53 | 53 |
{ |
54 |
scout_images_[i].LoadFile(
|
|
54 |
scout_images[i].LoadFile( |
|
55 | 55 |
wxString::FromAscii((images_path + scouts[i]).c_str())); |
56 |
scout_images_[i].SetMask(true);
|
|
57 |
scout_images_[i].SetMaskColour(255, 255, 255);
|
|
56 |
scout_images[i].SetMask(true); |
|
57 |
scout_images[i].SetMaskColour(255, 255, 255); |
|
58 | 58 |
} |
59 | 59 |
|
60 |
meter_ = scout_images_[0].GetHeight();
|
|
60 |
meter = scout_images[0].GetHeight();
|
|
61 | 61 |
|
62 |
path_bitmap_ = wxBitmap(GetSize().GetWidth(), GetSize().GetHeight());
|
|
63 |
path_dc_.SelectObject(path_bitmap_);
|
|
62 |
path_bitmap = wxBitmap(GetSize().GetWidth(), GetSize().GetHeight()); |
|
63 |
path_dc.SelectObject(path_bitmap);
|
|
64 | 64 |
clear(); |
65 | 65 |
|
66 |
clear_srv_ = nh_.advertiseService("clear",
|
|
66 |
clear_srv = nh.advertiseService("clear",
|
|
67 | 67 |
&SimFrame::clearCallback, this); |
68 |
reset_srv_ = nh_.advertiseService("reset",
|
|
68 |
reset_srv = nh.advertiseService("reset",
|
|
69 | 69 |
&SimFrame::resetCallback, this); |
70 |
spawn_srv_ = nh_.advertiseService("spawn",
|
|
70 |
spawn_srv = nh.advertiseService("spawn",
|
|
71 | 71 |
&SimFrame::spawnCallback, this); |
72 |
kill_srv_ = nh_.advertiseService("kill",
|
|
72 |
kill_srv = nh.advertiseService("kill",
|
|
73 | 73 |
&SimFrame::killCallback, this); |
74 | 74 |
|
75 | 75 |
ROS_INFO("Starting scoutsim with node name %s", |
76 | 76 |
ros::this_node::getName().c_str()) ; |
77 | 77 |
|
78 |
width_in_meters_ = GetSize().GetWidth() / meter_;
|
|
79 |
height_in_meters_ = GetSize().GetHeight() / meter_;
|
|
80 |
spawnScout("", width_in_meters_ / 2.0, height_in_meters_ / 2.0, 0);
|
|
78 |
width_in_meters = GetSize().GetWidth() / meter;
|
|
79 |
height_in_meters = GetSize().GetHeight() / meter;
|
|
80 |
spawnScout("", width_in_meters / 2.0, height_in_meters / 2.0, 0);
|
|
81 | 81 |
} |
82 | 82 |
|
83 | 83 |
SimFrame::~SimFrame() |
84 | 84 |
{ |
85 |
delete update_timer_;
|
|
85 |
delete update_timer; |
|
86 | 86 |
} |
87 | 87 |
|
88 | 88 |
bool SimFrame::spawnCallback(scoutsim::Spawn::Request& req, |
... | ... | |
103 | 103 |
bool SimFrame::killCallback(scoutsim::Kill::Request& req, |
104 | 104 |
scoutsim::Kill::Response&) |
105 | 105 |
{ |
106 |
M_Scout::iterator it = scouts_.find(req.name);
|
|
107 |
if (it == scouts_.end())
|
|
106 |
M_Scout::iterator it = scouts.find(req.name); |
|
107 |
if (it == scouts.end()) |
|
108 | 108 |
{ |
109 | 109 |
ROS_ERROR("Tried to kill scout [%s], which does not exist", |
110 | 110 |
req.name.c_str()); |
111 | 111 |
return false; |
112 | 112 |
} |
113 | 113 |
|
114 |
scouts_.erase(it);
|
|
114 |
scouts.erase(it); |
|
115 | 115 |
|
116 | 116 |
return true; |
117 | 117 |
} |
118 | 118 |
|
119 | 119 |
bool SimFrame::hasScout(const std::string& name) |
120 | 120 |
{ |
121 |
return scouts_.find(name) != scouts_.end();
|
|
121 |
return scouts.find(name) != scouts.end();
|
|
122 | 122 |
} |
123 | 123 |
|
124 | 124 |
std::string SimFrame::spawnScout(const std::string& name, float x, |
... | ... | |
130 | 130 |
do |
131 | 131 |
{ |
132 | 132 |
std::stringstream ss; |
133 |
ss << "scout" << ++id_counter_;
|
|
133 |
ss << "scout" << ++id_counter; |
|
134 | 134 |
real_name = ss.str(); |
135 | 135 |
} while (hasScout(real_name)); |
136 | 136 |
} |
... | ... | |
143 | 143 |
} |
144 | 144 |
|
145 | 145 |
ScoutPtr t(new Scout(ros::NodeHandle(real_name), |
146 |
scout_images_[rand() % SCOUTSIM_NUM_SCOUTS],
|
|
146 |
scout_images[rand() % SCOUTSIM_NUM_SCOUTS], |
|
147 | 147 |
Vector2(x, y), angle)); |
148 |
scouts_[real_name] = t;
|
|
148 |
scouts[real_name] = t; |
|
149 | 149 |
|
150 | 150 |
ROS_INFO("Spawning scout [%s] at x=[%f], y=[%f], theta=[%f]", |
151 | 151 |
real_name.c_str(), x, y, angle); |
... | ... | |
159 | 159 |
int g = DEFAULT_BG_G; |
160 | 160 |
int b = DEFAULT_BG_B; |
161 | 161 |
|
162 |
nh_.param("background_r", r, r);
|
|
163 |
nh_.param("background_g", g, g);
|
|
164 |
nh_.param("background_b", b, b);
|
|
162 |
nh.param("background_r", r, r); |
|
163 |
nh.param("background_g", g, g); |
|
164 |
nh.param("background_b", b, b); |
|
165 | 165 |
|
166 |
path_dc_.SetBackground(wxBrush(wxColour(r, g, b)));
|
|
167 |
path_dc_.Clear();
|
|
166 |
path_dc.SetBackground(wxBrush(wxColour(r, g, b))); |
|
167 |
path_dc.Clear(); |
|
168 | 168 |
} |
169 | 169 |
|
170 | 170 |
void SimFrame::onUpdate(wxTimerEvent& evt) |
... | ... | |
183 | 183 |
{ |
184 | 184 |
wxPaintDC dc(this); |
185 | 185 |
|
186 |
dc.DrawBitmap(path_bitmap_, 0, 0, true);
|
|
186 |
dc.DrawBitmap(path_bitmap, 0, 0, true); |
|
187 | 187 |
|
188 |
M_Scout::iterator it = scouts_.begin();
|
|
189 |
M_Scout::iterator end = scouts_.end();
|
|
188 |
M_Scout::iterator it = scouts.begin(); |
|
189 |
M_Scout::iterator end = scouts.end(); |
|
190 | 190 |
for (; it != end; ++it) |
191 | 191 |
{ |
192 | 192 |
it->second->paint(dc); |
... | ... | |
195 | 195 |
|
196 | 196 |
void SimFrame::updateScouts() |
197 | 197 |
{ |
198 |
if (last_scout_update_.isZero())
|
|
198 |
if (last_scout_update.isZero()) |
|
199 | 199 |
{ |
200 |
last_scout_update_ = ros::WallTime::now();
|
|
200 |
last_scout_update = ros::WallTime::now(); |
|
201 | 201 |
return; |
202 | 202 |
} |
203 | 203 |
|
204 |
if (frame_count_ % 3 == 0)
|
|
204 |
if (frame_count % 3 == 0) |
|
205 | 205 |
{ |
206 |
path_image_ = path_bitmap_.ConvertToImage();
|
|
206 |
path_image = path_bitmap.ConvertToImage();
|
|
207 | 207 |
Refresh(); |
208 | 208 |
} |
209 | 209 |
|
210 |
M_Scout::iterator it = scouts_.begin();
|
|
211 |
M_Scout::iterator end = scouts_.end();
|
|
210 |
M_Scout::iterator it = scouts.begin(); |
|
211 |
M_Scout::iterator end = scouts.end(); |
|
212 | 212 |
for (; it != end; ++it) |
213 | 213 |
{ |
214 |
it->second->update(0.016, path_dc_, path_image_,
|
|
215 |
path_dc_.GetBackground().GetColour(),
|
|
216 |
width_in_meters_, height_in_meters_);
|
|
214 |
it->second->update(0.016, path_dc, path_image,
|
|
215 |
path_dc.GetBackground().GetColour(), |
|
216 |
width_in_meters, height_in_meters);
|
|
217 | 217 |
} |
218 | 218 |
|
219 |
++frame_count_;
|
|
219 |
++frame_count; |
|
220 | 220 |
} |
221 | 221 |
|
222 | 222 |
|
... | ... | |
232 | 232 |
std_srvs::Empty::Response&) |
233 | 233 |
{ |
234 | 234 |
ROS_INFO("Resetting scoutsim."); |
235 |
scouts_.clear();
|
|
236 |
id_counter_ = 0;
|
|
237 |
spawnScout("", width_in_meters_ / 2.0, height_in_meters_ / 2.0, 0);
|
|
235 |
scouts.clear(); |
|
236 |
id_counter = 0; |
|
237 |
spawnScout("", width_in_meters / 2.0, height_in_meters / 2.0, 0);
|
|
238 | 238 |
clear(); |
239 | 239 |
return true; |
240 | 240 |
} |
scout/scoutsim/src/sim_frame.h | ||
---|---|---|
48 | 48 |
bool spawnCallback(scoutsim::Spawn::Request&, scoutsim::Spawn::Response&); |
49 | 49 |
bool killCallback(scoutsim::Kill::Request&, scoutsim::Kill::Response&); |
50 | 50 |
|
51 |
ros::NodeHandle nh_;
|
|
52 |
wxTimer* update_timer_;
|
|
53 |
wxBitmap path_bitmap_;
|
|
54 |
wxImage path_image_;
|
|
55 |
wxMemoryDC path_dc_;
|
|
51 |
ros::NodeHandle nh; |
|
52 |
wxTimer* update_timer; |
|
53 |
wxBitmap path_bitmap; |
|
54 |
wxImage path_image; |
|
55 |
wxMemoryDC path_dc; |
|
56 | 56 |
|
57 |
uint64_t frame_count_;
|
|
57 |
uint64_t frame_count; |
|
58 | 58 |
|
59 |
ros::WallTime last_scout_update_;
|
|
59 |
ros::WallTime last_scout_update; |
|
60 | 60 |
|
61 |
ros::ServiceServer clear_srv_;
|
|
62 |
ros::ServiceServer reset_srv_;
|
|
63 |
ros::ServiceServer spawn_srv_;
|
|
64 |
ros::ServiceServer kill_srv_;
|
|
61 |
ros::ServiceServer clear_srv; |
|
62 |
ros::ServiceServer reset_srv; |
|
63 |
ros::ServiceServer spawn_srv; |
|
64 |
ros::ServiceServer kill_srv; |
|
65 | 65 |
|
66 | 66 |
typedef std::map<std::string, ScoutPtr> M_Scout; |
67 |
M_Scout scouts_;
|
|
68 |
uint32_t id_counter_;
|
|
67 |
M_Scout scouts; |
|
68 |
uint32_t id_counter; |
|
69 | 69 |
|
70 |
wxImage scout_images_[SCOUTSIM_NUM_SCOUTS];
|
|
70 |
wxImage scout_images[SCOUTSIM_NUM_SCOUTS]; |
|
71 | 71 |
|
72 |
float meter_;
|
|
73 |
float width_in_meters_;
|
|
74 |
float height_in_meters_;
|
|
72 |
float meter; |
|
73 |
float width_in_meters; |
|
74 |
float height_in_meters; |
|
75 | 75 |
}; |
76 | 76 |
|
77 | 77 |
} |
Also available in: Unified diff