emc_system
io.cpp
Go to the documentation of this file.
1 #include "emc/io.h"
2 
3 #include "emc/communication.h"
4 
5 #include <ros/init.h> // for ros::ok()
6 #include <tf2/LinearMath/Transform.h>
7 #include <tf2_geometry_msgs/tf2_geometry_msgs.h>
8 #include <geometry_msgs/Pose.h>
9 #include <geometry_msgs/Quaternion.h>
10 #include <geometry_msgs/Vector3.h>
11 #include <visualization_msgs/Marker.h>
12 
13 #include <string>
14 
15 namespace emc
16 {
17 
18 IO::IO(Communication* comm) : comm_(comm)
19 {
20  if (!comm_)
21  comm_ = new Communication;
22 }
23 
24 IO::IO(std::string robot_name) : comm_(new Communication(robot_name))
25 {
26 }
27 
29 {
30  if (comm_)
31  delete comm_;
32 }
33 
35 {
36  return comm_->readLaserData(scan);
37 }
38 
40 {
41  return comm_->readPoseData(pose);
42 }
43 
45 {
46  OdometryData new_odom;
47  if (!comm_->readOdometryData(new_odom))
48  return false;
49 
50  if (!odom_set_)
51  {
52  ROS_WARN("Odom was not yet set. It is set now.");
53  prev_odom_ = new_odom;
54  odom_set_ = true;
55  return false;
56  }
57 
58  odom.timestamp = new_odom.timestamp; //TODO give dt?
59  double dx = new_odom.x - prev_odom_.x;
60  double dy = new_odom.y - prev_odom_.y;
61  odom.x = cos(prev_odom_.a) * dx + sin(prev_odom_.a) * dy;
62  odom.y = -sin(prev_odom_.a) * dx + cos(prev_odom_.a) * dy;
63  odom.a = fmod(new_odom.a - prev_odom_.a + 3*M_PI, 2*M_PI) - M_PI; // wrap to -pi +pi accounting for worst case values of odom and prev
64 
65  prev_odom_ = new_odom;
66  return true;
67 }
68 
70 {
71  OdometryData new_odom;
72  if (!comm_->readOdometryData(new_odom))
73  return false;
74  prev_odom_ = new_odom;
75  odom_set_ = true;
76  return true;
77 }
78 
80 {
81  return comm_->readFrontBumperData(bumper);
82 }
83 
85 {
86  return comm_->readBackBumperData(bumper);
87 }
88 
89 void IO::sendBaseReference(double vx, double vy, double va)
90 {
91  comm_->sendBaseVelocity(vx, vy, va);
92 }
93 
95 {
96  #pragma GCC diagnostic push
97  #pragma GCC diagnostic ignored "-Wunused-result"
98  system("aplay --device front:CARD=Device_1,DEV=0 ~/.emc/system/src/emc_system/sounds/doorbell.wav &");
99  #pragma GCC diagnostic pop
100 
102 }
103 
104 void IO::speak(const std::string& text)
105 {
106  //std::string cmd;
107  //cmd = "sudo espeak " + text + " --stdout | sudo aplay --device \"default:CARD=Device\"";
108  //cmd = "espeak " + text + " --stdout | aplay --device \"default:CARD=Device\" &";
109  //system(cmd.c_str());
110 
111  comm_->speak(text);
112 }
113 
114 void IO::play(const std::string& file)
115 {
116  comm_->play(file);
117 }
118 
119 bool IO::ok()
120 {
121  return ros::ok();
122 }
123 
124 bool IO::sendPath(std::vector<std::vector<double>> path, std::array<double, 3> color, double width, int id)
125 {
126  visualization_msgs::Marker pathMarker;
127  pathMarker.header.frame_id = "map";
128  pathMarker.header.stamp = ros::Time();
129  pathMarker.ns = "path";
130  pathMarker.id = id;
131  pathMarker.type = visualization_msgs::Marker::LINE_STRIP;
132  pathMarker.action = visualization_msgs::Marker::ADD;
133  pathMarker.color.a = 1.0;
134  pathMarker.color.r = color[0];
135  pathMarker.color.g = color[1];
136  pathMarker.color.b = color[2];
137  pathMarker.pose.orientation.w = 1.0;
138  pathMarker.scale.x = width;
139  for (std::vector<std::vector<double>>::iterator it = path.begin(); it != path.end(); ++it)
140  {
141  geometry_msgs::Point point;
142  if ((*it).size() < 2)
143  {
144  ROS_WARN_STREAM("Point at index " << std::distance(path.begin(), it) << " has too few dimensions (expected at least 2, got " << (*it).size() << "), skipping.");
145  continue;
146  }
147  point.x = (*it)[0];
148  point.y = (*it)[1];
149  if ((*it).size() == 2)
150  {
151  point.z = 0;
152  }
153  else
154  {
155  point.z = (*it)[3];
156  if ((*it).size() > 3)
157  {
158  ROS_WARN_STREAM("point at index " << std::distance(path.begin(), it) << " has unused dimensions (expected 2 or 3, got " << (*it).size() << ").");
159  }
160  }
161  pathMarker.points.push_back(point);
162  }
163  if (pathMarker.points.size() < 2)
164  {
165  ROS_ERROR_STREAM("Not enough valid points (expected at least 2, got " << pathMarker.points.size() << ").");
166  return false;
167  }
168  comm_->sendMarker(pathMarker);
169  return true;
170 }
171 
172 bool IO::sendPoseEstimate(double px, double py, double pz, double rx, double ry, double rz, double rw)
173 {
174  // apply map offset and send to comm_
175  tf2::Transform pose;
176  pose.setOrigin(tf2::Vector3(px, py, pz));
177  pose.setRotation(tf2::Quaternion(rx, ry, rz, rw));
178 
179  comm_->sendPoseEstimate(tf2::toMsg(pose));
180  return true;
181 }
182 
183 bool IO::sendPoseEstimate(double px, double py, double pz, double roll, double pitch, double yaw)
184 {
185  //convert roll pitch yaw to quaternion
186  tf2::Quaternion q;
187  q.setRPY(roll, pitch, yaw);
188  return this->sendPoseEstimate(px, py, pz, q.x(), q.y(), q.z(), q.w());
189 }
190 
191 bool IO::sendPoseEstimate(double x, double y, double yaw)
192 {
193  return this->sendPoseEstimate(x, y, 0, 0, 0, yaw);
194 }
195 
196 
197 // publishers used to visualize information in the localization exercises (particle filter):
198 
199 void IO::localization_viz_send_laser_scan(double angle_min, double angle_max, double angle_inc, int subsample, std::vector<float> prediction)
200 {
201  comm_->localization_viz_send_laser_scan(angle_min, angle_max, angle_inc, subsample, prediction);
202 }
203 
204 
205 void IO::localization_viz_send_particles(int N, std::vector<std::vector<double>> particle_poses, double mapOrientation)
206 {
207  comm_->localization_viz_send_particles(N, particle_poses, mapOrientation);
208 }
209 
210 
211 void IO::localization_viz_send_pose(std::vector<double> pose, double mapOrientation)
212 {
213  comm_->localization_viz_send_pose(pose, mapOrientation);
214 }
215 
216 }
emc::IO::readLaserData
bool readLaserData(LaserData &scan)
Receive new laser data if available.
Definition: io.cpp:34
std::string
emc::IO::localization_viz_send_laser_scan
void localization_viz_send_laser_scan(double angle_min, double angle_max, double angle_inc, int subsample, std::vector< float > prediction)
Definition: io.cpp:199
emc::IO::~IO
~IO()
Definition: io.cpp:28
emc::IO::IO
IO(Communication *comm=nullptr)
Definition: io.cpp:18
std::vector
emc::IO::readOdometryData
bool readOdometryData(OdometryData &odom)
Receive new odometrydata if available.
Definition: io.cpp:44
emc::Communication::sendPoseEstimate
void sendPoseEstimate(const geometry_msgs::Transform &pose)
Definition: communication.cpp:236
emc::IO::odom_set_
bool odom_set_
Definition: io.h:175
emc::PoseData
Definition: pose.h:9
std::distance
T distance(T... args)
emc::IO::sendPath
bool sendPath(std::vector< std::vector< double >> path, std::array< double, 3 > color={0.0, 0.0, 0.0}, double width=0.02, int id=0)
Send a path to be drawn in rviz.
Definition: io.cpp:124
emc::OdometryData::x
double x
Definition: odom.h:11
emc::Communication::readPoseData
bool readPoseData(PoseData &pose)
Definition: communication.cpp:107
emc::IO::resetOdometry
bool resetOdometry()
Set the current position as (0,0,0)
Definition: io.cpp:69
emc::Communication::readOdometryData
bool readOdometryData(OdometryData &odom)
Definition: communication.cpp:143
emc::OdometryData::a
double a
Definition: odom.h:13
emc::OdometryData
Definition: odom.h:9
emc::Communication::localization_viz_send_laser_scan
void localization_viz_send_laser_scan(double angle_min, double angle_max, double angle_inc, int subsample, std::vector< float > prediction)
Definition: communication.cpp:285
emc::LaserData
Definition: data.h:14
emc::Communication::localization_viz_send_particles
void localization_viz_send_particles(int N, std::vector< std::vector< double >> particle_poses, double mapOrientation)
Definition: communication.cpp:305
std::array
emc::IO::sendBaseReference
void sendBaseReference(double vx, double vy, double va)
Send a command velocity to the robot.
Definition: io.cpp:89
emc::Communication::sendBaseVelocity
void sendBaseVelocity(double vx, double vy, double va)
Definition: communication.cpp:195
emc::IO::readFrontBumperData
bool readFrontBumperData(BumperData &bumper)
Receive new BumperData from the front bumper.
Definition: io.cpp:79
emc::Communication::speak
void speak(const std::string &text)
Definition: communication.cpp:222
emc::Communication
Definition: communication.h:28
emc::IO::prev_odom_
OdometryData prev_odom_
Definition: io.h:174
communication.h
std::vector::begin
T begin(T... args)
emc::Communication::localization_viz_send_pose
void localization_viz_send_pose(std::vector< double > pose, double mapOrientation)
Definition: communication.cpp:334
emc::Communication::sendMarker
void sendMarker(visualization_msgs::Marker marker)
Definition: communication.cpp:215
emc::Communication::sendOpendoorRequest
void sendOpendoorRequest()
Definition: communication.cpp:207
emc::IO::localization_viz_send_particles
void localization_viz_send_particles(int N, std::vector< std::vector< double >> particle_poses, double mapOrientation)
Definition: io.cpp:205
emc::IO::ok
bool ok()
Check connection to the robot.
Definition: io.cpp:119
io.h
emc::IO::play
void play(const std::string &file)
Play a sound file out loud. The file must be placed in the ~/MRC_audio folder and must be of ....
Definition: io.cpp:114
emc::IO::localization_viz_send_pose
void localization_viz_send_pose(std::vector< double > pose, double mapOrientation)
Definition: io.cpp:211
emc
Definition: bumper.h:4
emc::IO::comm_
Communication * comm_
Definition: io.h:177
emc::OdometryData::y
double y
Definition: odom.h:12
emc::Communication::readFrontBumperData
bool readFrontBumperData(BumperData &bumper)
Definition: communication.cpp:165
emc::IO::sendOpendoorRequest
void sendOpendoorRequest()
Broadcast a request to open nearby doors. Works in simulator only.
Definition: io.cpp:94
emc::IO::readPoseData
bool readPoseData(PoseData &pose)
Receive new pose data if available.
Definition: io.cpp:39
emc::Communication::play
void play(const std::string &file)
Definition: communication.cpp:229
emc::Communication::readBackBumperData
bool readBackBumperData(BumperData &bumper)
Definition: communication.cpp:180
emc::IO::sendPoseEstimate
bool sendPoseEstimate(double x, double y, double yaw)
Send an estimate of the current robot pose to be shown in rviz, relative to the centre of the map (sa...
Definition: io.cpp:191
emc::Communication::readLaserData
bool readLaserData(LaserData &scan)
Definition: communication.cpp:86
emc::IO::readBackBumperData
bool readBackBumperData(BumperData &bumper)
Receive new BumperData from the rear bumper.
Definition: io.cpp:84
emc::OdometryData::timestamp
double timestamp
Definition: odom.h:14
emc::BumperData
Definition: bumper.h:9
emc::IO::speak
void speak(const std::string &text)
Make the robot speak the input text. This function is non-blocking.
Definition: io.cpp:104
string