Ethzasl MSF源码阅读(1):程序入口和主题订阅
关于IMU融合知乎上的一篇问答:有哪些开源项目是关于单目+imu做slam的?
Ethz的Stephen Weiss的工作,是一个IMU松耦合的方法。
1.程序入口:ethzasl_msf\msf_updates\src\pose_msf\main.cpp
#include "pose_sensormanager.h" int main(int argc, char** argv)
{
ros::init(argc, argv, "msf_pose_sensor");
msf_pose_sensor::PoseSensorManager manager;
ros::spin();
return ;
}
PoseSensorManager类,查看构造函数。PoseSensorManager继承自msf_core::MSF_SensorManagerROS,继承自msf_core::MSF_SensorManager<EKFState_T>
PoseSensorManager(ros::NodeHandle pnh = ros::NodeHandle("~/pose_sensor"))
{
bool distortmeas = false; //< Distort the pose measurements.
imu_handler_.reset(new msf_core::IMUHandler_ROS<msf_updates::EKFState>(*this, "msf_core", "imu_handler"));
pose_handler_.reset(new PoseSensorHandler_T(*this, "", "pose_sensor", distortmeas)); AddHandler(pose_handler_);
reconf_server_.reset(new ReconfigureServer(pnh));
ReconfigureServer::CallbackType f = boost::bind(&PoseSensorManager::Config, this, _1, _2);//回调
reconf_server_->setCallback(f);
init_scale_srv_ = pnh.advertiseService("initialize_msf_scale",
&PoseSensorManager::InitScale, this);
init_height_srv_ = pnh.advertiseService("initialize_msf_height",
&PoseSensorManager::InitHeight, this);
}
2. 注意其中的imu_handler_和pose_handler_,分别是IMUHandler_ROS对象和PoseSensorHandler模板类对象。IMUHandler_ROS继承自IMUHandler。
typedef PoseSensorHandler<msf_updates::pose_measurement::PoseMeasurement<>,
PoseSensorManager> PoseSensorHandler_T;
(msf_updates::pose_measurement::PoseMeasurement<>是模型类PoseSensorHandler的类参数,这是一个观测量参数。)
注意IMUHandler和PoseSensorHandler最终都继承自msf_core::SensorHandler<typename msf_updates::EKFState>类。
这两个类对象构造的时候都传入了*this指针,即PoseSensorManager对象自身。这很重要,两个类中都调用了PoseSensorManager的成员函数。
可以进入这两个类进行查看构造函数,这2个构造函数都进行了一些主题的订阅。
IMUHandler_ROS构造,同时查看IMUHandler_ROS::IMUCallback回调函数。
IMUHandler_ROS(MSF_SensorManager<EKFState_T>& mng,
const std::string& topic_namespace, const std::string& parameternamespace)
: IMUHandler<EKFState_T>(mng, topic_namespace, parameternamespace)
{
ros::NodeHandle nh(topic_namespace);
subImu_ = nh.subscribe("imu_state_input", , &IMUHandler_ROS::IMUCallback, this);
subState_ = nh.subscribe("hl_state_input", , &IMUHandler_ROS::StateCallback, this);
}
PoseSensorHandler构造,同时查看PoseSensorHandler::MeasurementCallback回调函数。
template<typename MEASUREMENT_TYPE, typename MANAGER_TYPE>
PoseSensorHandler<MEASUREMENT_TYPE, MANAGER_TYPE>::PoseSensorHandler(
MANAGER_TYPE& meas, std::string topic_namespace,
std::string parameternamespace, bool distortmeas)
: SensorHandler<msf_updates::EKFState>(meas, topic_namespace, parameternamespace),
n_zp_(1e-),
n_zq_(1e-),
delay_(),
timestamp_previous_pose_()
{
ros::NodeHandle pnh("~/" + parameternamespace); MSF_INFO_STREAM(
"Loading parameters for pose sensor from namespace: "
<< pnh.getNamespace()); pnh.param("pose_absolute_measurements", provides_absolute_measurements_,
true);
pnh.param("pose_measurement_world_sensor", measurement_world_sensor_, true);
pnh.param("pose_use_fixed_covariance", use_fixed_covariance_, false);
pnh.param("pose_measurement_minimum_dt", pose_measurement_minimum_dt_, 0.05);
pnh.param("enable_mah_outlier_rejection", enable_mah_outlier_rejection_, false);
pnh.param("mah_threshold", mah_threshold_, msf_core::kDefaultMahThreshold_); MSF_INFO_STREAM_COND(measurement_world_sensor_, "Pose sensor is interpreting "
"measurement as sensor w.r.t. world");
MSF_INFO_STREAM_COND(
!measurement_world_sensor_,
"Pose sensor is interpreting measurement as world w.r.t. "
"sensor (e.g. ethzasl_ptam)"); MSF_INFO_STREAM_COND(use_fixed_covariance_, "Pose sensor is using fixed "
"covariance");
MSF_INFO_STREAM_COND(!use_fixed_covariance_,
"Pose sensor is using covariance "
"from sensor"); MSF_INFO_STREAM_COND(provides_absolute_measurements_,
"Pose sensor is handling "
"measurements as absolute values");
MSF_INFO_STREAM_COND(!provides_absolute_measurements_, "Pose sensor is "
"handling measurements as relative values"); ros::NodeHandle nh("msf_updates/" + topic_namespace);
subPoseWithCovarianceStamped_ =
nh.subscribe < geometry_msgs::PoseWithCovarianceStamped
> ("pose_with_covariance_input", , &PoseSensorHandler::MeasurementCallback, this);
subTransformStamped_ = nh.subscribe < geometry_msgs::TransformStamped
> ("transform_input", , &PoseSensorHandler::MeasurementCallback, this);
subPoseStamped_ = nh.subscribe < geometry_msgs::PoseStamped
> ("pose_input", , &PoseSensorHandler::MeasurementCallback, this); z_p_.setZero();
z_q_.setIdentity(); if (distortmeas)
{
Eigen::Vector3d meanpos;
double distortpos_mean;
pnh.param("distortpos_mean", distortpos_mean, 0.0);
meanpos.setConstant(distortpos_mean); Eigen::Vector3d stddevpos;
double distortpos_stddev;
pnh.param("distortpos_stddev", distortpos_stddev, 0.0);
stddevpos.setConstant(distortpos_stddev); Eigen::Vector3d meanatt;
double distortatt_mean;
pnh.param("distortatt_mean", distortatt_mean, 0.0);
meanatt.setConstant(distortatt_mean); Eigen::Vector3d stddevatt;
double distortatt_stddev;
pnh.param("distortatt_stddev", distortatt_stddev, 0.0);
stddevatt.setConstant(distortatt_stddev); double distortscale_mean;
pnh.param("distortscale_mean", distortscale_mean, 0.0);
double distortscale_stddev;
pnh.param("distortscale_stddev", distortscale_stddev, 0.0); distorter_.reset( new msf_updates::PoseDistorter(meanpos, stddevpos, meanatt, stddevatt, distortscale_mean, distortscale_stddev));
}
}
3.reconf_server_->setCallback(f)绑定了一个回调,回调函数PoseSensorManager::Config(xx).
virtual void Config(Config_T &config, uint32_t level)
{
config_ = config;
pose_handler_->SetNoises(config.pose_noise_meas_p,
config.pose_noise_meas_q);
pose_handler_->SetDelay(config.pose_delay);
if ((level & msf_updates::SinglePoseSensor_INIT_FILTER)
&& config.core_init_filter == true)
{
Init(config.pose_initial_scale);
config.core_init_filter = false;
}
// Init call with "set height" checkbox.
if ((level & msf_updates::SinglePoseSensor_SET_HEIGHT)
&& config.core_set_height == true)
{
Eigen::Matrix<double, , > p = pose_handler_->GetPositionMeasurement();
if (p.norm() == )
{
MSF_WARN_STREAM(
"No measurements received yet to initialize position. Height init "
"not allowed.");
return;
}
double scale = p[] / config.core_height;
Init(scale);
config.core_set_height = false;
}
}
参考文献:
多传感器卡尔曼融合框架 Ethzasl MSF Framework 编译与使用
Ethzasl MSF源码阅读(1):程序入口和主题订阅的更多相关文章
- Ethzasl MSF源码阅读(3):MSF_Core和PoseMeasurement
1.MSF_Core的三个函数:ProcessIMU.ProcessExternallyPropagatedState和AddMeasurement MSF_Core维护了状态队列和观测值队列,这里需 ...
- Ethzasl MSF源码阅读(2):百川汇海
这里有个感觉,就是百川汇海.即IMU数据和相机的消息数据都汇集到msf_core进行处理.接上一篇, 1. 查看IMUHandler_ROS::IMUCallback和IMUHandler_ROS:: ...
- MYC编译器源码分析之程序入口
前文.NET框架源码解读之MYC编译器讲了MyC编译器的架构,整个编译器是用C#语言写的,上图列出了MyC编译器编译一个C源文件的过程,编译主路径如下: 首先是入口Main函数用来解析命令行参数,读取 ...
- CI框架源码阅读笔记2 一切的入口 index.php
上一节(CI框架源码阅读笔记1 - 环境准备.基本术语和框架流程)中,我们提到了CI框架的基本流程,这里再次贴出流程图,以备参考: 作为CI框架的入口文件,源码阅读,自然由此开始.在源码阅读的过程中, ...
- fw: 专访许鹏:谈C程序员修养及大型项目源码阅读与学习
C家最近也有一篇关于如何阅读大型c项目源代码的文章,学习..融合.. -------------------- ref:http://www.csdn.net/article/2014-06-05 ...
- CI框架源码阅读笔记4 引导文件CodeIgniter.php
到了这里,终于进入CI框架的核心了.既然是“引导”文件,那么就是对用户的请求.参数等做相应的导向,让用户请求和数据流按照正确的线路各就各位.例如,用户的请求url: http://you.host.c ...
- CI框架源码阅读笔记1 - 环境准备、基本术语和框架流程
最开始使用CI框架的时候,就打算写一个CI源码阅读的笔记系列,可惜虎头蛇尾,一直没有行动.最近项目少,总算是有了一些时间去写一些东西.于是准备将之前的一些笔记和经验记录下来,一方面权作备忘,另一方面时 ...
- Spring源码阅读笔记
前言 作为一个Java开发者,工作了几年后,越发觉力有点不从心了,技术的世界实在是太过于辽阔了,接触的东西越多,越感到前所未有的恐慌. 每天捣鼓这个捣鼓那个,结果回过头来,才发现这个也不通,那个也不精 ...
- Settings-Sync插件源码阅读
一.介绍 请参考官网: https://marketplace.visualstudio.com/items?itemName=Shan.code-settings-sync 二.源码目录详解 Ima ...
随机推荐
- ServiceMesh究竟解决什么问题?
服务网格(ServiceMesh)这两年异常之火,号称是下一代微服务架构,互联网公司经常使用的是微服务分层架构. 随着数据量不断增大,吞吐量不断增加,业务越来越复杂,服务的个数会越来越多,分层会越来越 ...
- Git 子模块 - submodule(转)
原文地址: http://www.cnblogs.com/kelsen/p/5918672.html 有种情况我们经常会遇到:某个工作中的项目需要包含并使用另一个项目. 也许是第三方库,或者你 独立开 ...
- perl控制流介绍(if条件,while,for循环,foreach)
1. 语句块:{ }之间的部分即为BLOCK语句块. 2. 条件语句:if ( expression ) BLOCK; if ( expression ) BLOCK1else BLOCK2 ...
- Direct3D 11 Tutorial 3: Shaders and Effect System_Direct3D 11 教程3:着色器和效果系统
概述 在上一个教程中,我们设置了一个顶点缓冲区并将一个三角形传递给GPU. 现在,我们将逐步完成图形管道并查看每个阶段的工作原理. 将解释着色器和效果系统的概念. 请注意,本教程与前一个源代码共享相同 ...
- win2003 序列号 windows2003 sp2可用序列号大全(准版与企业版)
通用性好的win2003序列号: (推荐先用这个里面的) FJ8DH-TQPYG-9KFHQ-88CB2-Y7V3Y GRD4P-FTQQF-JCDM8-4P6JK-PFG7M JD7JX-KCDTH ...
- 媳妇要转java开发,我该怎么办?
我是一名5年的java开发者,媳妇是一个5年的软件实施工程师,我们结婚快一年了,这几天她突然对我说,她想转java开发,让我辅导她学习java,我该怎么弄,我心底是不愿意她转开发的,毕竟她年龄也不小了 ...
- 局域网ARP攻击防护
通过借助一些安全软件来实现局域网ARP检测及防御功能. A.电脑管家 电脑管家--工具箱--下载ARP防火墙模块 不支持window2003 B.服务器安全狗 Windows版下载:http://fr ...
- classmethod作用
>>> class A(object): bar = 1 def func1(self): print 'foo' >>> class A(object): bar ...
- 【Zookeeper系列】ZooKeeper管理分布式环境中的数据(转)
原文地址:https://www.cnblogs.com/sunddenly/p/4092654.html 引言 本节本来是要介绍ZooKeeper的实现原理,但是ZooKeeper的原理比较复杂,它 ...
- windows上,任务管理器中,进程命令行太长怎么办
一.前言 在windows上,有时候需要查看进程命令行,但是有的进程的命令行太长了,很难看全 此时,可以使用下面的方法解决(红框改为自己要查看的进程即可): C:\Users\Gaoyu>wmi ...