target_type: 'aprilgrid'#gridtype tagCols: 6 #number of apriltags tagRows: 6 #number of apriltags tagSize: 0.035 #size of apriltag, edge to edge [m] tagSpacing: 0.3 #ratio of space between tags to tagSize
A ROS package tool to analyze the IMU performance. C++ version of Allan Variance Tool. The figures are drawn by Matlab, in scripts.
Actually, just analyze the Allan Variance for the IMU data. Collect the data while the IMU is Stationary, with a two hours duration. code_utils标定IMU的噪音密度和随机游走系数。
The following packages have unmet dependencies: libdw-dev : Depends: libelf-dev but it is not going to be installed Depends: libdw1 (= 0.165-3ubuntu1) but it is not going to be installed E: Unable to correct problems, you have held broken packages.
这是因为一个依赖项已经安装了不同版本:Depends: libelf1 (= 0.165-3ubuntu1) but 0.165-3ubuntu1.2 is to be installed。 解决方法: sudo aptitude install libdw-dev,对给出的方案,选择第二个,降级 libelf1[0.165-3ubuntu1.1 (now) -> 0.158-0ubuntu]
启动: roslaunch realsense2_camera rs_imu_calibration.launch,然后录制imu数据包rosbag record -O imu_calibration /camera/imu,让IMU静止不动两个小时,录制IMU的bag.
标定
根据imu_utils文件夹里面的A3.launch改写D435i标定启动文件:d435i_imu_calib.launch注意,记得修改max_time_min对应的参数,默认是120,也就是两个小时,如果ros包里的imu数据长度没有两个小时,等bag播放完了,还是停留在wait for imu data这里,不会生成标定文件。我录了1小时59分多一点,所以还得改成119
gyr x numData 781205 gyr x start_t 1.59343e+09 gyr x end_t 1.59344e+09 gyr x dt -------------7140.59 s -------------119.01 min -------------1.9835 h gyr x freq 109.403 gyr x period 0.00914049 gyr y numData 781205 gyr y start_t 1.59343e+09 gyr y end_t 1.59344e+09 gyr y dt -------------7140.59 s -------------119.01 min -------------1.9835 h gyr y freq 109.403 gyr y period 0.00914049 gyr z numData 781205 gyr z start_t 1.59343e+09 gyr z end_t 1.59344e+09 gyr z dt -------------7140.59 s -------------119.01 min -------------1.9835 h gyr z freq 109.403 gyr z period 0.00914049 Gyro X C -6.83161 94.2973 -19.0588 2.983 -0.0404918 Bias Instability 2.37767e-05 rad/s Bias Instability 6.28462e-05 rad/s, at 63.1334 s White Noise 12.9453 rad/s White Noise 0.00360015 rad/s bias -0.363298 degree/s ------------------- Gyro y C -8.74367 117.584 -15.9277 2.47408 -0.0373467 Bias Instability 6.41864e-05 rad/s Bias Instability 7.52073e-05 rad/s, at 104.256 s White Noise 16.8998 rad/s White Noise 0.00471573 rad/s bias -0.544767 degree/s ------------------- Gyro z C -4.51808 68.1919 -9.33284 1.95333 -0.0262641 Bias Instability 8.50869e-05 rad/s Bias Instability 7.19998e-05 rad/s, at 63.1334 s White Noise 9.43212 rad/s White Noise 0.00268623 rad/s bias -0.0762471 degree/s ------------------- ============================================== ============================================== acc x numData 781205 acc x start_t 1.59343e+09 acc x end_t 1.59344e+09 acc x dt -------------7140.59 s -------------119.01 min -------------1.9835 h acc x freq 109.403 acc x period 0.00914049 acc y numData 781205 acc y start_t 1.59343e+09 acc y end_t 1.59344e+09 acc y dt -------------7140.59 s -------------119.01 min -------------1.9835 h acc y freq 109.403 acc y period 0.00914049 acc z numData 781205 acc z start_t 1.59343e+09 acc z end_t 1.59344e+09 acc z dt -------------7140.59 s -------------119.01 min -------------1.9835 h acc z freq 109.403 acc z period 0.00914049 acc X C 3.36177e-05 0.00175435 -0.000159698 7.23303e-05 -7.16006e-07 Bias Instability 0.000553948 m/s^2 White Noise 0.018272 m/s^2 ------------------- acc y C 9.36955e-05 0.00234733 0.00012197 0.000243676 -2.66252e-06 Bias Instability 0.00156748 m/s^2 White Noise 0.0289241 m/s^2 ------------------- acc z C 5.07832e-05 0.00331104 -0.000381222 0.000199602 -2.43776e-06 Bias Instability 0.00115308 m/s^2 White Noise 0.0351134 m/s^2
Principal Point : 327.438, 239.997 Focal Length : 611.354, 610.016 Distortion Model : Inverse Brown Conrady Distortion Coefficients : [0,0,0,0,0]
疑难问题 undefined symbol: _ZN2cv3MatC1Ev
运行rs_camera.launch时报错
1
symbol lookup error: /home/jetson/catkin_ws/devel/lib//librealsense2_camera.so: undefined symbol: _ZN2cv3MatC1Ev [camera/realsense2_camera_manager-2] process has died
RealSense ROS v2.3.2 [ INFO] [1723892537.013079361]: Built with LibRealSense v2.50.0 [ INFO] [1723892537.013109698]: Running with LibRealSense v2.50.0 [ INFO] [1723892537.311113159]: Device with serial number 014122072296 was found. [ INFO] [1723892537.311624883]: Device with physical ID 2-1.4-6 was found. [ INFO] [1723892537.311852281]: Device with name Intel RealSense D435I was found. [ INFO] [1723892537.313360062]: Device with port number 2-1.4 was found. [ INFO] [1723892537.313859786]: Device USB type: 3.2
inlinevoidGridSlamProcessor::scanMatch(constdouble* plainReading) { // sample a new pose from each scan in the reference /* 每个粒子都要进行 scan-match */ double sumScore=0; int particle_number = m_particles.size(); //可以用openMP的方式来进行并行化,因此这里不能用迭代器,只能用下标的方式 //并行化之后,里面的循环会均匀分到各个不同的核里面 for (int i = 0; i < particle_number; i++) { OrientedPoint corrected; double score, l, s; /*进行scan-match 计算粒子的最优位姿,这是gmapping本来的做法*/ score = m_matcher.optimize(corrected, m_particles[i].map, m_particles[i].pose, plainReading); /* 匹配成功则更新最优位姿 */ if (score>m_minimumScore) { m_particles[i].pose = corrected; } /* 扫描匹配不上,则使用里程计的数据,使用里程计数据不进行更新. 因为在进行扫描匹配之前 里程计已经更新过了*/ else { if (m_infoStream) { m_infoStream << "Scan Matching Failed, using odometry. Likelihood=" << l <<std::endl; m_infoStream << "lp:" << m_lastPartPose.x << " " << m_lastPartPose.y << " "<< m_lastPartPose.theta <<std::endl; m_infoStream << "op:" << m_odoPose.x << " " << m_odoPose.y << " "<< m_odoPose.theta; } } // 粒子的最优位姿计算了之后,重新计算粒子的权重,相当于粒子滤波器中的观测步骤 /* 计算p(z|x,m),粒子的权重由粒子的似然来表示, 计算粒子的得分和权重(似然) 注意粒子的权重经过ScanMatch之后已经更新了 * 在论文中 粒子的权重不是用最优位姿的似然值来表示的 * 是用所有的似然值的和来表示的, s是得分 l是似然,也就是权重 */ m_matcher.likelihoodAndScore(s, l, m_particles[i].map, m_particles[i].pose, plainReading); sumScore+=score; m_particles[i].weight+= l; m_particles[i].weightSum+= l;
//set up the selective copy of the active area //by detaching the areas that will be updated /*计算出来最优的位姿之后,进行地图的扩充 这里不会进行内存分配 *不进行内存分配的原因是这些粒子进行重采样之后有可能会消失掉,因此在后面进行重采样的时候统一进行内存分配。 *理论上来说,这里的操作是没有必要的,因为后面的重采样的时候还会进行一遍 */ m_matcher.invalidateActiveArea(); m_matcher.computeActiveArea(m_particles[i].map, m_particles[i].pose, plainReading); } if (m_infoStream) m_infoStream << "Average Scan Matching Score of all particles=" << sumScore/m_particles.size(); }
对于栅格地图的环境地图模型,一般采用基于似然场模型(likelihood field range finder mode)的扫描匹配算法来进行激光雷达数据与地图的匹配。 该算法通过评估当前时刻位姿的激光雷达数据中每一个激光点与该时刻栅格地图的匹配程度,并将评估得到的每个激光点得分进行累加,得到当前时刻激光雷达数据与地图匹配的总分数,得分越高说明该时刻激光雷达信息与地图匹配程度越高,即机器人位姿越精确。由于该算法能够根据机器人当前时刻状态、 观测值和地图信息直接得到该时刻位姿的匹配程度,因而该算法常与基于粒子滤波的定位算法结合使用,用于选取各粒子中得分最高的位姿,并计算得分, 从而完成机器人位姿的确定,其原理如图:
sumScore+=score; m_particles[i].weight+=l; m_particles[i].weightSum+=l; //set up the selective copy of the active area //by detaching the areas that will be updated /*计算出来最优的位姿之后,进行地图的扩充 这里不会进行内存分配 *不进行内存分配的原因是这些粒子进行重采样之后有可能会消失掉,因此在后面进行冲采样的时候统一进行内存分配。 *理论上来说,这里的操作是没有必要的,因为后面的重采样的时候还会进行一遍 */ m_matcher.invalidateActiveArea(); m_matcher.computeActiveArea(m_particles[i].map, m_particles[i].pose, plainReading);
// the map may have expanded, so resize ros message as well // 扩充地图的大小 if(map_.map.info.width != (unsignedint) smap.getMapSizeX() || map_.map.info.height != (unsignedint) smap.getMapSizeY()) {
// NOTE: The results of ScanMatcherMap::getSize() are different from the parameters given to the constructor // so we must obtain the bounding box in a different way GMapping::Point wmin = smap.map2world(GMapping::IntPoint(0, 0)); GMapping::Point wmax = smap.map2world(GMapping::IntPoint(smap.getMapSizeX(), smap.getMapSizeY())); xmin_ = wmin.x; ymin_ = wmin.y; xmax_ = wmax.x; ymax_ = wmax.y;
ROS_DEBUG("map size is now %dx%d pixels (%f,%f)-(%f, %f)", smap.getMapSizeX(), smap.getMapSizeY(), xmin_, ymin_, xmax_, ymax_);
//make sure to set the header information on the map //把计算出来的地图发布出去 map_.map.header.stamp = ros::Time::now(); map_.map.header.frame_id = tf_.resolve( map_frame_ );