Gmapping_slam
问题1:[warn]:TF_REPEATED_DATA ignoring data with redundant timestamp for frame wamv/base_link at time 7.267000 according to authority unknown_publisher
如果查看tf没有问题再使用roswtf查看,大多数情况是相同的tf多次发布
问题2:Gmapping 只适用于 单帧二维激光点数小于1440的点,如果单帧激光点数大于1440,那么就会出现[mapping-4] process has died
这样的问题。
点数计算: ranges[ ] = round(max_angle-min_angle)/angle_increment+1
注意可能与实际点数多一个或者两个,由取整以及+1决定
记录3:wamv没有里程计,因此用的robot_location定位包gps与imu融合输出的robot_location/odometry/filterd话题输出的Nav_msgs/Odometry消息,但是这样odom坐标原点由datum定义,是经纬度。。。。。
<remap from="/wamv/robot_localization/odometry/filtered" to="/odom"/>
记录4:
wamv_planar_lidar: 平面激光雷达 未安装!!!
wamv_pinger:声纳
xacro文件的使用:
<!-- 属性定义 -->
<xacro:property name="PI" value="3.1415927" />
<!-- 宏定义 -->
<xacro:macro name="wheel_func" params="wheel_name flag" >
<joint name="${0.1*flag}${wheel_name}2link" type="continuous">
<!-- 属性调用 -->
<axis xyz="PI 1 0" />
</joint>
</xacro:macro>
<!-- 宏调用-->
<xacro:wheel_func wheel_name="left" flag="1" />
向wamv添加wamv_planar_lidar:
//复制原wamv
roscp wamv_gazebo wamv_gazebo.urdf.xacro my_wamv.urdf.xacro
//添加平面雷达
<xacro:wamv_multibeam_laser name="planar_lidar_wamv" />
//生成urdf文件
rosrun xacro xacro my_wamv.urdf.xacro > my_wamv.urdf
//修改launch文件
<arg name="urdf" default="$(find wamv_gazebo)/urdf/my_wamv.urdf.xacro"/>
hector_slam
问题1:Hector仅使用激光雷达建图,经常出SearchDir angle change too larg
原因:rplidar出现剧烈移动或抖动,又或者周边环境在发生大的变化。
因为是水域随海浪涌动会产生很大的飘移,导致飘出地图
另外的原因是选择的参数超出了阈值或者雷达性能较低,建议发布频率50hz以上
因此将波浪引起的运动改为平坦的海洋(无波浪)。可以通过两种方式实现:
选项 1:更改全局默认参数。
编辑文件,将增益值更改为零,使其如下所示。wave_gazebo/world_models/ocean_waves/model.xacro
<xacro:macro name=“ocean_waves” params=“gain:=0.0 period:=5
direction_x:=1.0 direction_y:=0.0
angle:=0.4”>
现在,对于未显式设置增益参数而使用宏的任何世界,增益参数的值将为零。因此,所有的波幅都将为零平坦的海洋。
选项 2:更改本地参数。
第二个选项是在调用宏时显式设置参数。例如,编辑 以在调用宏时将 gain 参数设置为零:vrx_gazebo/worlds/example_course.world.xacro
<!--Waves-->
<xacro:include filename="$(find wave_gazebo)/world_models/ocean_waves/model.xacro"/>
<xacro:ocean_waves gain="0.0"/>
注意,需要运行才能使更改生效。catkin_make
问题2:要想在没有tf的条件下也能map需要进行以下修改:
<param name="pub_map_odom_transform" value="true"/>
<param name="map_frame" value="map" />
<param name="base_frame" value="base_frame" />
<param name="odom_frame" value="base_frame" />
并且在HectorMappingRos.cpp的81行把true改为false,参照238行的条件判断。
private_nh_.param("use_tf_scan_transformation", p_use_tf_scan_transformation_,false);
雷达
ros中的雷达数据格式:sensor_msgs/LsaerScan.msg
std_msgs/Header header
uint32 seq
time stamp
string frame_id
float32 angle_min # start angle of the scan [rad]
float32 angle_max # end angle of the scan [rad]
float32 angle_increment # angular distance between measurements [rad]
float32 time_increment
float32 scan_time # time between scans [seconds]
float32 range_min # minimum range value [m]
float32 range_max # maximum range value [m]
float32[] ranges # range data [m]
#(Note: values < range_min or > range_max should be discarded)
float32[] intensities # intensity data [device-specific units].
注意: ranges数组表示雷达旋转时,记录从angle_min到angle_max 角度范围内的距离数据,(angle_max-angle_min) /angle_increment 即是数组的大小,序号从angle_min开始,即angle_min对应的序号为0,intensities与ranges对应,记录每个数据点的强度或者是激光雷达的反射率。
对于pointcloud_to_laserscan功能包:注意修改其中的:*
angle_increment: 0.017 //不要太小也不要太大,对slam有影响
range_min: 0.45
range_max: 100.0 //否则效果不好
gazebo通过插件实现雷达功能
<plugin name="gazebo_rplidar" filename="libgazebo_ros_laser.so">
<plugin name="gazebo_rplidar" filename="libgazebo_ros_gpu_laser.so">
关键参数
<samples>360</samples> //采样个数,雷达旋转一周采样数
<resolution>1</resolution> //分辨率,每N个射线测距一次
<min_angle>-3</min_angle> //采样范围,单位是弧度,以机器人朝向为中心,
<max_angle>3</max_angle> //逆时针为正,顺时针为负
//每圈产生的激光数量num = samples * resolution
那这样resolution和angle_increment没区别吧
获取gazebo中物体真实位置
添加插件:
<gazebo>
<plugin name="p3d_plugin_${name}" filename="libgazebo_ros_p3d.so">
<bodyName>${namespace}/base_link</bodyName>
<frameName>map</frameName>
<updateRate>10.0</updateRate>
<topicName>${namespace}/${sensor_namespace}position/${name}</topicName>
<xyzOffset>0 0 0</xyzOffset>
<rpyOffset>0 0 0</rpyOffset>
<gaussianNoise>0</gaussianNoise>
</plugin>
</gazebo>
在Gazebo仿真中经常要订阅/ground_truth/state话题获得Gazebo中模型的位置信息(Gazebo是xyz坐标系) ,/ground_truth/state 话题是由插件libgazebo_ros_p3d.so发出的。默认情况下,我们使用的通过apt-get 的方式安装到ros目录下面的so(so是插件文件)文件。
libgazebo_ros_p3d.so只有订阅/ground_truth/state话题了,才会发消息。
差分推力
right_thrust_cmd = Twist.linear.x + Twist.angular.z
left_thrust_cmd = Twist.linear.x - Twist.angular.z
use_sim_time
ROS::Time[/Duration/Rate]:ROS时间——来源可以被认为修改如加速/减速/暂停。true : /clock
ROS::WallTime[WallDuration/WallRate]:ROS绝对时间——不可修改的"真实"时间。false
ROS网络中的时间是指,如果当时在非仿真环境里运行,那它就是当前的时间。但是假设去回放当时的情况,那就需要把当时的时间录下来。以控制为例,很多的数据处理需要知道当时某一个时刻发生了什么。Wall Time可以理解为墙上时间,墙上挂着的时间没有人改变的了,永远在往前走;ROS Time可以被人为修改,你可以暂停它,可以加速,可以减速,但是Wall Time不可以。
在开启一个Node之前,当把use_sim_time设置为true时,这个节点会从clock Topic获得时间。所以操作这个clock的发布者,可以实现一个让Node中得到ROS Time暂停、加速、减速的效果。同时下面这些方面都是跟Node透明的,所以非常适合离线的调试方式。当把ROSbag记下来以后重新play出来时,加两个横杠,–clock,它就会发布出这个消息。
在录制rosbag的时候msg/header/stamp时间戳是录制时刻的值。可能导致当前ROS时间 和时间戳不匹配导致:抛出异常,更有甚者直接功能不正常。我们可以设置use_sim_time再启动节点,改变ROS时间源。并通过对rosbag … --clock参数让rosbag发布/clock驱动ROS时间