上回说道添加轨迹函数Node::AddTrajectory
中的订阅话题与注册回调函数,在此之前计算了一个由topicname和sensor类型组合成的一个集合expected_sensor_ids,轨迹IDtrajectory_id,新添加了一个位姿估计器,一个传感器采样器以及如何订阅topic和注册回调函数。下面我们介绍node.cc>Node::AddTrajectory中的定时器以及topic检查
1 2 3
| wall_timers_.push_back(node_handle_.createWallTimer( ::ros::WallDuration(kTopicMismatchCheckDelaySec), &Node::MaybeWarnAboutTopicMismatch, this, true));
|
walltimers定义
1 2 3
|
std::vector<::ros::WallTimer> wall_timers_;
|
这是一个WallTimer的vector。
定时器
上面这个定时器
1 2 3
| node_handle_.createWallTimer( ::ros::WallDuration(kTopicMismatchCheckDelaySec), &Node::MaybeWarnAboutTopicMismatch, this, true)
|
每kTopicMismatchCheckDelaySec个时间运行Node::MaybeWarnAboutTopicMismatch函数一次。oneshot
表示只执行一次。
MaybeWarnAboutTopicMismatch
此函数用于检查topic的订阅名字是否正确
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| void Node::MaybeWarnAboutTopicMismatch( const ::ros::WallTimerEvent& unused_timer_event) {
::ros::master::V_TopicInfo ros_topics; ::ros::master::getTopics(ros_topics);
std::set<std::string> published_topics; std::stringstream published_topics_string;
for (const auto& it : ros_topics) { std::string resolved_topic = node_handle_.resolveName(it.name, false); published_topics.insert(resolved_topic); published_topics_string << resolved_topic << ","; }
bool print_topics = false; for (const auto& entry : subscribers_) { int trajectory_id = entry.first; for (const auto& subscriber : entry.second) {
std::string resolved_topic = node_handle_.resolveName(subscriber.topic);
if (published_topics.count(resolved_topic) == 0) { LOG(WARNING) << "Expected topic \"" << subscriber.topic << "\" (trajectory " << trajectory_id << ")" << " (resolved topic \"" << resolved_topic << "\")" << " but no publisher is currently active."; print_topics = true; } } } if (print_topics) { LOG(WARNING) << "Currently available topics are: " << published_topics_string.str(); } }
|
获取master里所有topic
1 2 3
| ::ros::master::V_TopicInfo ros_topics; ::ros::master::getTopics(ros_topics);
|
获取ros中实际topic的全局名称并放入
1 2 3 4 5 6
| for (const auto& it : ros_topics) { std::string resolved_topic = node_handle_.resolveName(it.name, false); published_topics.insert(resolved_topic); published_topics_string << resolved_topic << ","; }
|
获取所有订阅者的topic
1 2 3 4 5 6
| for (const auto& entry : subscribers_) { int trajectory_id = entry.first; for (const auto& subscriber : entry.second) { ... } }
|
subscribers_是一个std::unordered_map,键为轨迹ID,即 entry.first;,值为一个订阅者的vector, entry.second
匹配订阅的topic和实际在ros中已经有的topic
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| for (const auto& entry : subscribers_) { int trajectory_id = entry.first; for (const auto& subscriber : entry.second) {
std::string resolved_topic = node_handle_.resolveName(subscriber.topic);
if (published_topics.count(resolved_topic) == 0) { LOG(WARNING) << "Expected topic \"" << subscriber.topic << "\" (trajectory " << trajectory_id << ")" << " (resolved topic \"" << resolved_topic << "\")" << " but no publisher is currently active."; print_topics = true; } } }
|
通过循环订阅者,查看订阅者所订阅的topic是不是均在ros的现有topic中,如果不在则报错