cartographer源码分析(22)-sensor-collator.h
来源:互联网 发布:网络错误代码10071 编辑:程序博客网 时间:2024/06/06 23:59
源码可在https://github.com/learnmoreonce/SLAM 下载
文件:sensor/collator.h#ifndef CARTOGRAPHER_SENSOR_COLLATOR_H_#define CARTOGRAPHER_SENSOR_COLLATOR_H_#include <functional>#include <memory>#include <unordered_map>#include <unordered_set>#include <vector>#include "cartographer/sensor/data.h"#include "cartographer/sensor/ordered_multi_queue.h"namespace cartographer {namespace sensor {/*Collator,采集者,校对者,整理者将多传感器采集的数据归并到轨迹上。Collator类:不可拷贝,不可赋值.只有一个默认构造函数.有2个数据成员1,OrderedMultiQueue queue_; key是pair<轨迹线id,传感器id>.一般情况下,对于已有的bag文件,轨迹id等于0.2,std::unordered_map<int, std::vector<QueueKey>> queue_keys_轨迹线和队列key组成的hash表,1:N模式Collator类主要提供三个操作:1,AddTrajectory() 添加一个轨迹线,2,FinishTrajectory() 标记轨迹线已经采集完成3,AddSensorData()接收传感器数据4,Flush()刷新*/class Collator { public: using Callback = std::function<void(const string&, std::unique_ptr<Data>)>; Collator() {} Collator(const Collator&) = delete; Collator& operator=(const Collator&) = delete;/*添加一个轨迹线,接受有序的传感器数据,并使用callback回调处理data。 一个轨迹线对应多个传感器数据:id ->unordered_set*/ // Adds a trajectory to produce sorted sensor output for. Calls 'callback' // for each collated sensor data. void AddTrajectory(int trajectory_id, const std::unordered_set<string>& expected_sensor_ids, Callback callback); // Marks 'trajectory_id' as finished.标记轨迹线已经完成采样. void FinishTrajectory(int trajectory_id);/*添加一个传感器id对应的数据data,数据必须按时间排序,*/ // Adds 'data' for 'trajectory_id' to be collated. 'data' must contain valid // sensor data. Sensor packets with matching 'sensor_id' must be added in time // order. void AddSensorData(int trajectory_id, const string& sensor_id, std::unique_ptr<Data> data);//刷新 // Dispatches all queued sensor packets. May only be called once. // AddSensorData may not be called after Flush. void Flush();/*返回阻塞的轨迹id,此种情况多见于某一传感器持久未采集data,造成ordered_multi_queue阻塞。 */ // Must only be called if at least one unfinished trajectory exists. Returns // the ID of the trajectory that needs more data before the Collator is // unblocked. int GetBlockingTrajectoryId() const; private: //多个key构成的多队列 // Queue keys are a pair of trajectory ID and sensor identifier. OrderedMultiQueue queue_; //int为传感器id,vector是id+sensor组成的QueueKey // Map of trajectory ID to all associated QueueKeys. std::unordered_map<int, std::vector<QueueKey>> queue_keys_;};} // namespace sensor} // namespace cartographer#endif // CARTOGRAPHER_SENSOR_COLLATOR_H_
.
文件:collator.cc#include "cartographer/sensor/collator.h"namespace cartographer {namespace sensor {/*一个轨迹线,多个传感器*//*struct QueueKey { int trajectory_id;// 轨线id; string sensor_id; //传感器id }*/void Collator::AddTrajectory( const int trajectory_id, const std::unordered_set<string>& expected_sensor_ids, const Callback callback) { for (const auto& sensor_id : expected_sensor_ids) { //对于每一个轨迹线+传感器,设置一个key const auto queue_key = QueueKey{trajectory_id, sensor_id}; //添加一个名为key的队列,并设置回调函数处理data queue_.AddQueue(queue_key, [callback, sensor_id](std::unique_ptr<Data> data) { callback(sensor_id, std::move(data)); }); //map<int,vector<key>>:添加轨迹线对应的key queue_keys_[trajectory_id].push_back(queue_key); }}/*队列不再接收数据*/void Collator::FinishTrajectory(const int trajectory_id) { for (const auto& queue_key : queue_keys_[trajectory_id]) { queue_.MarkQueueAsFinished(queue_key); }}/*主要的操作,添加传感器数据,数据形式是:key+data*/void Collator::AddSensorData(const int trajectory_id, const string& sensor_id, std::unique_ptr<Data> data) { //找到key,再move(data) queue_.Add(QueueKey{trajectory_id, sensor_id}, std::move(data));}void Collator::Flush() { queue_.Flush(); }int Collator::GetBlockingTrajectoryId() const { return queue_.GetBlocker().trajectory_id;}} // namespace sensor} // namespace cartographer
测试代码:collator_test.cc#include "cartographer/sensor/collator.h"#include <array>#include <memory>#include "cartographer/common/lua_parameter_dictionary_test_helpers.h"#include "cartographer/common/make_unique.h"#include "cartographer/common/time.h"#include "cartographer/sensor/proto/sensor.pb.h"#include "gtest/gtest.h"namespace cartographer {namespace sensor {namespace {TEST(Collator, Ordering) { const std::array<string, 4> kSensorId = { {"horizontal_rangefinder", "vertical_rangefinder", "imu", "odometry"}}; Data zero(common::FromUniversal(0), Data::Rangefinder{}); Data first(common::FromUniversal(100), Data::Rangefinder{}); Data second(common::FromUniversal(200), Data::Rangefinder{}); Data third(common::FromUniversal(300), Data::Imu{}); Data fourth(common::FromUniversal(400), Data::Rangefinder{}); Data fifth(common::FromUniversal(500), Data::Rangefinder{}); Data sixth(common::FromUniversal(600), transform::Rigid3d::Identity()); //构造6个传感器数据 std::vector<std::pair<string, Data>> received; Collator collator; collator.AddTrajectory( //添加一个轨迹线0,多个传感器,并指定回调函数:所有的接收数据都存储在received中 0, std::unordered_set<string>(kSensorId.begin(), kSensorId.end()), [&received](const string& sensor_id, std::unique_ptr<Data> data) { received.push_back(std::make_pair(sensor_id, *data)); //由传感器id和data组成一个pair }); constexpr int kTrajectoryId = 0; // Establish a common start time. collator.AddSensorData(kTrajectoryId, kSensorId[0], common::make_unique<Data>(zero)); //轨迹0,传感器0产生一个数据,产生时间是0us collator.AddSensorData(kTrajectoryId, kSensorId[1], common::make_unique<Data>(zero)); collator.AddSensorData(kTrajectoryId, kSensorId[2], common::make_unique<Data>(zero)); collator.AddSensorData(kTrajectoryId, kSensorId[3], common::make_unique<Data>(zero)); //同上 collator.AddSensorData(kTrajectoryId, kSensorId[0], common::make_unique<Data>(first));//产生数据 collator.AddSensorData(kTrajectoryId, kSensorId[3], common::make_unique<Data>(sixth)); collator.AddSensorData(kTrajectoryId, kSensorId[0], common::make_unique<Data>(fourth)); collator.AddSensorData(kTrajectoryId, kSensorId[1], common::make_unique<Data>(second)); collator.AddSensorData(kTrajectoryId, kSensorId[1], common::make_unique<Data>(fifth)); collator.AddSensorData(kTrajectoryId, kSensorId[2], common::make_unique<Data>(third));/*h:{0,100,400}v:{0,200,500}i:{0,300}o:{0,600}*/ ASSERT_EQ(7, received.size()); //{0,0,0,0,100,200,300} EXPECT_EQ(100, common::ToUniversal(received[4].second.time)); EXPECT_EQ(kSensorId[0], received[4].first); EXPECT_EQ(200, common::ToUniversal(received[5].second.time)); EXPECT_EQ(kSensorId[1], received[5].first); EXPECT_EQ(300, common::ToUniversal(received[6].second.time)); EXPECT_EQ(kSensorId[2], received[6].first); collator.Flush(); //刷新 ASSERT_EQ(10, received.size()); //10个数据,所有sensor采集的数据 EXPECT_EQ(kSensorId[0], received[7].first); EXPECT_EQ(500, common::ToUniversal(received[8].second.time)); EXPECT_EQ(kSensorId[1], received[8].first); EXPECT_EQ(600, common::ToUniversal(received[9].second.time)); EXPECT_EQ(kSensorId[3], received[9].first);}} // namespace} // namespace sensor} // namespace cartographer
本文发于:
* http://www.jianshu.com/u/9e38d2febec1
* https://zhuanlan.zhihu.com/learnmoreonce
* http://blog.csdn.net/learnmoreonce
* slam源码分析微信公众号:slamcode
阅读全文
0 0
- cartographer源码分析(22)-sensor-collator.h
- cartographer源码分析(17)-sensor-point_cloud.h
- cartographer源码分析(19)-sensor-range_data.h
- cartographer源码分析(20)-sensor-data.h
- cartographer源码分析(21)-sensor-ordered_multi_queue.h
- cartographer源码分析(23)-sensor-voxel_filter.h
- cartographer源码分析(24)-sensor-configuration.h
- cartographer源码分析(18)-sensor-compressed_point_cloud
- cartographer源码分析(3)-common-port.h
- cartographer源码分析(4)-common-time.h
- cartographer源码分析(5)-common-rate_time.h
- cartographer源码分析(6)-common-histogram.h
- cartographer源码分析(7)-common-math.h
- cartographer源码分析(8)-common-make_unique.h
- cartographer源码分析(5)-common-fixed_ratio_sampler.h
- cartographer源码分析(9)-common-mutex.h
- cartographer源码分析(10)-common-thread_pool.h
- cartographer源码分析(11)-common-blocking_queue.h
- XlistView+Xutils+PhotoView
- Java异常处理
- 高精度乘法 普通(n^2)+fft(nlogn)
- 【MFC】【精心整理】【实用】visual C++中最常用的类与API函数
- 我的Android学习之路01-GridView
- cartographer源码分析(22)-sensor-collator.h
- 关于linkedList和ArrayList的一些比较
- Jsp的内置对象(重点)
- Java语言实现的扫雷游戏(一)
- UNP源码使用及编译
- 如何在Java中使用双重检查锁实现单例
- Android中解析XML
- GalaxyOJ-37 (Tarjan+缩点)
- cartographer源码分析(23)-sensor-voxel_filter.h