41 #include <visualization_msgs/Marker.h> 42 #include <nav_msgs/Odometry.h> 50 namespace rcd = dynamics;
53 bool Protobuf2RosStream::startReceivingAndPublishingAsRos()
55 unsigned int timeoutMillis = 500;
59 unsigned int cntNoListener = 0;
62 while (!_stop && !failed)
67 bool someoneListens = checkRosPublishersUsed();
71 if (++cntNoListener > 200)
81 ROS_INFO_STREAM(
"rc_visard_driver: Enabled rc-dynamics stream: " << _stream);
85 rcd::DataReceiver::Ptr receiver;
86 while (!_stop && someoneListens && !receiver)
88 someoneListens = checkRosPublishersUsed();
91 receiver = _rcdyn->createReceiverForStream(_stream);
92 receiver->setTimeout(timeoutMillis);
93 ROS_INFO_STREAM(
"rc_visard_driver: rc-dynamics stream ready: " << _stream);
95 catch (rcd::RemoteInterface::DynamicsNotRunning& e)
98 msg <<
"Could not initialize rc-dynamics stream: " << _stream <<
":" << endl << e.what();
99 msg <<
"\nWaiting until rc_dynamics node is running...." << endl;
100 msg <<
"\(Hint: Use one of this node's /dynamics_start* services.)" << endl;
107 ROS_ERROR_STREAM(std::string(
"Could not initialize rc-dynamics stream: ") + _stream +
": " + e.what());
116 string pbMsgType = _rcdyn->getPbMsgTypeOfStream(_stream);
117 shared_ptr<::google::protobuf::Message> pbMsg;
118 unsigned int consecutive_timeouts = 0;
119 while (!_stop && someoneListens)
121 someoneListens = checkRosPublishersUsed();
125 pbMsg = receiver->receive(pbMsgType);
128 catch (std::exception& e)
130 ROS_ERROR_STREAM(
"Caught exception during receiving " << _stream <<
": " << e.what());
142 string state = _rcdyn->getDynamicsState();
143 if (state != rcd::RemoteInterface::State::RUNNING &&
144 state != rcd::RemoteInterface::State::RUNNING_WITH_SLAM)
146 ROS_WARN_STREAM_THROTTLE(30,
"Not receiving any " << _stream <<
" messages because rc_visard's dynamics node is in state " << state <<
"!");
149 }
catch (exception& e)
151 ROS_ERROR_STREAM(
"Did not receive any " << _stream <<
" message within the last " << timeoutMillis <<
" ms. " 152 <<
"Could not access state of rc_visard's rc_dynamics module: " << e.what());
158 string stream_dest = receiver->getIpAddress() +
":" + std::to_string(receiver->getPort());
159 list<string> active_destinations = _rcdyn->getDestinationsOfStream(_stream);
160 if (std::find(active_destinations.begin(), active_destinations.end(), stream_dest) == active_destinations.end())
162 ROS_WARN_STREAM(
"Not receiving any " << _stream <<
" messages because rc_visard stopped streaming to destination " 163 << stream_dest <<
"! (Did someone delete this stream destination?) Re-creating stream... ");
168 if (++consecutive_timeouts>3) {
170 ROS_WARN_STREAM_THROTTLE(1,
"Did not receive any " << _stream <<
" message within the last " << timeoutMillis <<
" ms. " 171 <<
"There seems to problems with your network or connection to rc_visard! Resetting stream..." 172 <<
"(Please check https://tutorials.roboception.de/rc_visard_general/network_setup for proper network setup!)");
185 ROS_INFO_STREAM(
"rc_visard_driver: Disabled rc-dynamics stream: " << _stream);
193 void Protobuf2RosStream::initRosPublishers()
195 string pbMsgType = _rcdyn->getPbMsgTypeOfStream(_stream);
196 _rosPublisher = shared_ptr<Protobuf2RosPublisher>(
new Protobuf2RosPublisher(_nh, _stream, pbMsgType, _tfPrefix));
199 bool Protobuf2RosStream::checkRosPublishersUsed()
201 return _rosPublisher->used();
204 void Protobuf2RosStream::publishToRos(shared_ptr<::google::protobuf::Message> pbMsg)
206 _rosPublisher->publish(pbMsg);
209 void PoseAndTFStream::initRosPublishers()
211 Protobuf2RosStream::initRosPublishers();
215 bool PoseAndTFStream::checkRosPublishersUsed()
217 return Protobuf2RosStream::checkRosPublishersUsed() || _tfEnabled ;
220 void PoseAndTFStream::publishToRos(shared_ptr<::google::protobuf::Message> pbMsg)
222 Protobuf2RosStream::publishToRos(pbMsg);
224 shared_ptr<roboception::msgs::Frame> protoFrame = dynamic_pointer_cast<roboception::msgs::Frame>(pbMsg);
227 protoFrame->set_parent(_tfPrefix + protoFrame->parent());
228 protoFrame->set_name(_tfPrefix + protoFrame->name());
234 _tf_pub->sendTransform(transform);
239 void DynamicsStream::initRosPublishers()
243 _publishVisualizationMarkers =
false;
244 ros::NodeHandle(
"~").param(
"enable_visualization_markers", _publishVisualizationMarkers, _publishVisualizationMarkers);
245 _publishVisualizationMarkers = _publishVisualizationMarkers && (_stream ==
"dynamics");
249 _pub_odom = shared_ptr<ros::Publisher>(
new ros::Publisher(_nh.advertise<nav_msgs::Odometry>(_stream, 1000)));
250 if (_publishVisualizationMarkers)
253 _nh.advertise<visualization_msgs::Marker>(
"dynamics_visualization_markers", 1000)));
255 if (_publishImu2CamAsTf)
261 bool DynamicsStream::checkRosPublishersUsed()
263 return _pub_odom->getNumSubscribers() > 0 || (_publishVisualizationMarkers && _pub_markers->getNumSubscribers() > 0);
266 void DynamicsStream::publishToRos(shared_ptr<::google::protobuf::Message> pbMsg)
268 shared_ptr<roboception::msgs::Dynamics> protoMsg = dynamic_pointer_cast<roboception::msgs::Dynamics>(pbMsg);
271 protoMsg->set_pose_frame(_tfPrefix + protoMsg->pose_frame());
272 protoMsg->set_linear_velocity_frame(_tfPrefix + protoMsg->linear_velocity_frame());
273 protoMsg->set_angular_velocity_frame(_tfPrefix + protoMsg->angular_velocity_frame());
274 protoMsg->set_linear_acceleration_frame(_tfPrefix + protoMsg->linear_acceleration_frame());
275 protoMsg->mutable_cam2imu_transform()->set_name(_tfPrefix + protoMsg->cam2imu_transform().name());
276 protoMsg->mutable_cam2imu_transform()->set_parent(_tfPrefix + protoMsg->cam2imu_transform().parent());
282 if (_publishImu2CamAsTf)
286 auto imu2cam =
tf::StampedTransform(cam2imu.inverse(), msgStamp, cam2imu.child_frame_id_, cam2imu.frame_id_);
287 _tf_pub->sendTransform(imu2cam);
295 auto odom = boost::make_shared<nav_msgs::Odometry>();
296 odom->header.frame_id = protoMsg->pose_frame();
297 odom->header.stamp = msgStamp;
298 odom->child_frame_id = protoMsg->linear_acceleration_frame();
299 odom->pose.pose = *
toRosPose(protoMsg->pose());
301 auto lin_vel = protoMsg->linear_velocity();
302 auto lin_vel_transformed = imu2world_rot_only.inverse() *
tf::Vector3(lin_vel.x(), lin_vel.y(), lin_vel.z());
303 odom->twist.twist.linear.
x = lin_vel_transformed.x();
304 odom->twist.twist.linear.y = lin_vel_transformed.y();
305 odom->twist.twist.linear.z = lin_vel_transformed.z();
306 auto ang_vel = protoMsg->angular_velocity();
307 odom->twist.twist.angular.x = ang_vel.x();
308 odom->twist.twist.angular.y = ang_vel.y();
309 odom->twist.twist.angular.z = ang_vel.z();
310 _pub_odom->publish(odom);
313 if (_publishVisualizationMarkers)
315 geometry_msgs::Point start, end;
316 auto protoPosePosition = protoMsg->pose().position();
317 start.x = protoPosePosition.x();
318 start.y = protoPosePosition.y();
319 start.z = protoPosePosition.z();
321 visualization_msgs::Marker lin_vel_marker;
322 lin_vel_marker.header.stamp = msgStamp;
323 lin_vel_marker.header.frame_id = protoMsg->linear_velocity_frame();
324 lin_vel_marker.ns = _tfPrefix;
325 lin_vel_marker.id = 0;
326 lin_vel_marker.type = visualization_msgs::Marker::ARROW;
327 lin_vel_marker.action = visualization_msgs::Marker::MODIFY;
328 lin_vel_marker.frame_locked =
true;
329 end.x = start.x + lin_vel.x();
330 end.y = start.y + lin_vel.y();
331 end.z = start.z + lin_vel.z();
332 lin_vel_marker.points.push_back(start);
333 lin_vel_marker.points.push_back(end);
334 lin_vel_marker.scale.x = 0.005;
335 lin_vel_marker.scale.y = 0.01;
336 lin_vel_marker.color.a = 1;
337 lin_vel_marker.color.g = lin_vel_marker.color.b = 1.0;
338 _pub_markers->publish(lin_vel_marker);
340 visualization_msgs::Marker ang_vel_marker;
341 ang_vel_marker.header.stamp = msgStamp;
342 ang_vel_marker.header.frame_id = protoMsg->pose_frame();
343 ang_vel_marker.ns = _tfPrefix;
344 ang_vel_marker.id = 1;
345 ang_vel_marker.type = visualization_msgs::Marker::ARROW;
346 ang_vel_marker.action = visualization_msgs::Marker::MODIFY;
347 ang_vel_marker.frame_locked =
true;
348 auto ang_vel_transformed = imu2world_rot_only *
tf::Vector3(ang_vel.x(), ang_vel.y(), ang_vel.z());
349 end.
x = start.x + ang_vel_transformed.x();
350 end.y = start.y + ang_vel_transformed.y();
351 end.z = start.z + ang_vel_transformed.z();
352 ang_vel_marker.points.push_back(start);
353 ang_vel_marker.points.push_back(end);
354 ang_vel_marker.scale.x = 0.005;
355 ang_vel_marker.scale.y = 0.01;
356 ang_vel_marker.color.a = 1;
357 ang_vel_marker.color.r = ang_vel_marker.color.b = 1.0;
358 _pub_markers->publish(ang_vel_marker);
360 visualization_msgs::Marker lin_accel_marker;
361 lin_accel_marker.header.stamp = msgStamp;
362 lin_accel_marker.header.frame_id = protoMsg->pose_frame();
363 lin_accel_marker.ns = _tfPrefix;
364 lin_accel_marker.id = 2;
365 lin_accel_marker.type = visualization_msgs::Marker::ARROW;
366 lin_accel_marker.action = visualization_msgs::Marker::MODIFY;
367 lin_accel_marker.frame_locked =
true;
368 auto lin_accel = protoMsg->linear_acceleration();
369 auto lin_accel_transformed = imu2world_rot_only *
tf::Vector3(lin_accel.x(), lin_accel.y(), lin_accel.z());
370 end.
x = start.x + lin_accel_transformed.x();
371 end.y = start.y + lin_accel_transformed.y();
372 end.z = start.z + lin_accel_transformed.z();
373 lin_accel_marker.points.push_back(start);
374 lin_accel_marker.points.push_back(end);
375 lin_accel_marker.scale.x = 0.005;
376 lin_accel_marker.scale.y = 0.01;
377 lin_accel_marker.color.a = 1;
378 lin_accel_marker.color.r = lin_accel_marker.color.g = 1.0;
380 _pub_markers->publish(lin_accel_marker);
tf::Transform toRosTfTransform(const roboception::msgs::Pose &pose)
Generic implementation for publishing protobuf messages to ros.
TFSIMD_FORCE_INLINE const tfScalar & x() const
#define ROS_WARN_STREAM(args)
#define ROS_WARN_STREAM_THROTTLE(rate, args)
#define ROS_INFO_STREAM(args)
#define ROS_ERROR_STREAM(args)
geometry_msgs::PosePtr toRosPose(const roboception::msgs::Pose &pose)
ros::Time toRosTime(const roboception::msgs::Time &time)
tf::StampedTransform toRosTfStampedTransform(const roboception::msgs::Frame &frame)