文章目录
boost::filesystem的使用
boost::filesystem的使用
更好的filesystem
[filesystem的官方例程]
ubuntu16.04安装boost
(https://www.boost.org/doc/libs/1_73_0/libs/filesystem/doc/tutorial.html)‘
问题总结:
1.sudo apt-get install 安装在usr/lib里,cmake找不到的。因此,boost应该用源码安装,这样就会安装在/usr/local/lib里。而CMakeLists.txt里直接使用Boost_INCLUDE_DIR之类即可。
2.在windows上使用了1.73什么都可以,而在ubuntu上安装的是1.70,用boost::filesystem::exists(path)的时候总是会报段错误。
3.想换版本了怎么办? 一个方法是直接删除/usr/local/include 和/usr/local/lib里的boost文件夹,然后安装新的版本。或者直接安装,这样应该会覆盖掉原来的,但估计如果新版本删了一些文件的话,还是会有残留。
由于boost已经被我更改了,可能会影响到hdl,所以我想单独编译一个包。
方法是在catkin_ws目录下,
catkin_make --only-pkg-with-deps lidar_localization
这样我就只编译了lidar_localization.
GLog的用法
GLog用法
但这里面的安装里 ./autogen.sh是没有办法运行的,会提示没有相应命令,这时候,需要安装libtool。
Glog和Gflags的安装
但我还没学会cmake中给他链接第三方库的方法。
g++的用法
g++用法
-I[dir]
在你是用#include "file"的时候,gcc/g++会先在当前目录查找你所指定的头文件,如果没有找到,会到系统默认的头文件目录找。如果使用-I指定了目录,编译器会先在指定的目录查找,然后再去系统默认头文件目录查找。对于#include ,gcc/g++会到-I指定的目录查找,查找不到,然后再到系统默认的头文件目录查找。
ros::Rate
创建一个对象,用于设置运行的频率。ros::spinOnce与ros::spin。
在ROS里面,消息回调函数并不是一接收到消息就做处理。而是需要等到运行spinOnce,
spin才开始统一处理callback。
ros::Rate rate(100);
while (ros::ok()) {
ros::spinOnce();
_front_end_flow_ptr->Run();
rate.sleep();
}
上面代码意味着,程序运行频率为100Hz,即100Hz启动一次callback,并且执行run。其余的时间以sleep度过,以保证该频率。
算法精度评估
视觉SLAM算法精度评估
其中还包括了对evo的使用。
比较常用的命令如下:
# 对轨迹进行可视化,kitti不太清楚是什么含义,可能是指明数据集,以确定读取的格式。后面是两个txt文本。
# 用`--ref=`来修饰可以表示参考轨迹,
# -a表示align,即将轨迹尽可能通过旋转和平移进行配准,配准后可以看出闭环检测的影响。
evo_traj kitti ground_truth.txt laser_odom.txt -p --plot_mode=xy
# 计算rpe,即相对姿态误差,可以反映rotate和transform的误差。delta 100,相当于每100m算一次。
# 反映了百分比。
evo_rpe kitti ground_truth.txt laser_odom.txt -r trans_part --delta 100 --plot --plot_mode xyz
# 计算ape,即绝对姿态误差。
evo_ape kitti ground_truth.txt laser_odom.txt -r full --plot --plot_mode xyz
Eigen的类型
Eigen库的使用
Isometry是4*4的,
Eigen3版本查看
存于/usr/include/eigen3/Eigen/src/Core/util/Macros.h.
如果是通过安装包装的,那就是在/usr/local/include里。
坐标系
内旋与外旋
内在旋转,转动矩阵右乘;外在旋转,转动矩阵左乘;内在旋转与外在旋转的绕轴旋转序列倒序时,两者等效。这描述的是机器人学欧拉角表示的时候。
实际上,最终不管内旋外旋,得到的一个旋转矩阵都一样,用于坐标变换 也都是左乘坐标的。
而坐标系变换的话,其实相当于让坐标系里的点,做了相反的旋转。
比如T表示坐标系A旋转到坐标系A‘,则坐标系里的点,相当于做了T(-1)操作。即P’=T(-1) * P。坐标原点的姿态,A’=TA。
所以,我越来越不理解为什么会有右乘。
而ROS中TF是这样的:
tf-overview
tf若查询的是B with repect to A的矩阵,(这代表了A是referance frame,B是target referance),则将B中的数据转换到A来,只需要左乘tf即可。
tf变换存储的是将坐标系"frame_id"变换到"child_frame_id"的坐标系变换,也即将数据在"child_frame_id"坐标系下转换到在"frame_id"下表示。
也就是说 T左乘可以将child里的数据转换到frame里,也可以把frame坐标系变到与child一致。
参考了 ROStf详解
回到最开始问题的起因,在那个代码里,作者使用了imu *= lidar_to_imu,在最终版本里,
c++的singal信号处理
ROS里的PointCloud2
ROS单独编译与还原
如果要在工作空间中构建特定的程序包,请在工作空间的根目录中调用以下命令:
$ catkin_make -DCATKIN_WHITELIST_PACKAGES =“ package1; package2”
如果要还原为生成所有软件包,请执行以下操作:
$ catkin_make -DCATKIN_WHITELIST_PACKAGES =“”
C++原子操作
深度和距离
深度是距离在相机z轴的投影。一般相机的z轴向前,X向左,Y向上。
git不用输入密码了
四元数的简化计算
git stash
fitnessscore
template <typename PointSource, typename PointTarget, typename Scalar> inline double
Registration<PointSource, PointTarget, Scalar>::getFitnessScore (double max_range)
{
double fitness_score = 0.0;
// Transform the input dataset using the final transformation
PointCloudSource input_transformed;
transformPointCloud (*input_, input_transformed, final_transformation_);
std::vector<int> nn_indices (1);
std::vector<float> nn_dists (1);
// For each point in the source dataset
int nr = 0;
for (std::size_t i = 0; i < input_transformed.points.size (); ++i)
{
// Find its nearest neighbor in the target
tree_->nearestKSearch (input_transformed.points[i], 1, nn_indices, nn_dists);
// Deal with occlusions (incomplete targets)
if (nn_dists[0] <= max_range)
{
// Add to the fitness score
fitness_score += nn_dists[0];
nr++;
}
}
if (nr > 0)
return (fitness_score / nr);
return (std::numeric_limits<double>::max ());
}
总结一下,配准得分,就是将source点云用配准得到的矩阵T变换到target点云里,然后用K-近邻法去找变换后的source在target里的最近点,并累加他们之间的欧氏距离,而最后得分输出时还要除以点对数。也就是说,registration返回的fitness_score是点云中的点在两个点云中的平均距离的平方。
显然,得分越高,则说明变换以后的点云差异性越大。
但这个得分是一个相对的概念,只能用于同一数据集的比较。因为,假设有一组点云本身就变化很细微,而另一组点云存在大量高速移动物体,那么前者的得分必然远低于后者,而与算法本身的效果无关。
另外,由于对所有的点都遍历了,所以必然会影响程序的整体速度。
ROS_INFO_NAMED
https://www.ncnynl.com/archives/201702/1299.html
ROS::Pointcloud与Pointcloud2之间的转换
栅格地图的实现
c++中include<>和include""区别
#include<>直接从编译器自带的函数库中寻找文件,#include""是先从自定义的文件中找 ,如果找不到在从函数库中寻找文件。
也就是说,如果确保自己要使用的是原生库,最好用<>,如string.h,而自己写的最好“”,加快编译速度。