赞
踩
我是中秋解加了一天班刚到家的小鱼,先祝大家中秋快乐~
在机器人导航过程中,实时的位置计算是非常重要的,一般我们可以通过轮子的编码器根据机器人的运动学模型性计算出里程计信息,但在一些特殊场景下,比如机器人轮子在原地打滑,此时机器人并没有动但此时对轮子进行积分计算的里程计显示机器人在不断的移动,此时IMU可以检测到机器人并未移动(没有任何方向上的加速度)。初次之外还有另外一种场景,机器人在原地画月饼,结果被人给绑架了(抬起来),移动一段距离,此时轮子没有转,里程计数据表示机器人没有动,此时IMU可以检测出机器人其实动了。
所以如果能有一种方法将IMU和里程计数据进行融合,之后给出一个更加准确的里程计信息,ros2里个功能包实现了这一功能。
这个功能报就是robot localization
功能包ekf_node
,该功能包使用扩展卡尔曼滤波器来融合里程信息并发布 odom => base_link
变换。
我们使用fishbot开源库进行测试学习:https://github.com/fishros/fishbot
首先,安装 robot_localization
包,二进制安装
sudo apt install ros-$ROS_DISTRO-robot-localization
源码安装:
git clone https://github.com/cra-ros-pkg/robot_localization -b humble-devel
在src/fishbot_navigation2/config
下创建ekf.yaml
输入下面内容
### ekf config file ### ekf_filter_node: ros__parameters: # The frequency, in Hz, at which the filter will output a position estimate. Note that the filter will not begin # computation until it receives at least one message from one of theinputs. It will then run continuously at the # frequency specified here, regardless of whether it receives more measurements. Defaults to 30 if unspecified. frequency: 30.0 # ekf_localization_node and ukf_localization_node both use a 3D omnidirectional motion model. If this parameter is # set to true, no 3D information will be used in your state estimate. Use this if you are operating in a planar # environment and want to ignore the effect of small variations in the ground plane that might otherwise be detected # by, for example, an IMU. Defaults to false if unspecified. two_d_mode: false # Whether to publish the acceleration state. Defaults to false if unspecified. publish_acceleration: true # Whether to broadcast the transformation over the /tf topic. Defaultsto true if unspecified. publish_tf: true # 1. Set the map_frame, odom_frame, and base_link frames to the appropriate frame names for your system. # 1a. If your system does not have a map_frame, just remove it, and make sure "world_frame" is set to the value of odom_frame. # 2. If you are fusing continuous position data such as wheel encoder odometry, visual odometry, or IMU data, set "world_frame" # to your odom_frame value. This is the default behavior for robot_localization's state estimation nodes. # 3. If you are fusing global absolute position data that is subject to discrete jumps (e.g., GPS or position updates from landmark # observations) then: # 3a. Set your "world_frame" to your map_frame value # 3b. MAKE SURE something else is generating the odom->base_link transform. Note that this can even be another state estimation node # from robot_localization! However, that instance should *not* fuse the global data. map_frame: map # Defaults to "map" if unspecified odom_frame: odom # Defaults to "odom" if unspecified base_link_frame: base_link # Defaults to "base_link" ifunspecified world_frame: odom # Defaults to the value ofodom_frame if unspecified odom0: /odom odom0_config: [true, true, true, false, false, false, false, false, false, false, false, true, false, false, false] imu0: /imu imu0_config: [false, false, false, true, true, true, false, false, false, false, false, false, false, false, false]
关于这些参数的含义可以参考:http://docs.ros.org/en/melodic/api/robot_localization/html/state_estimation_nodes.html#parameters
新建src/fishbot_navigation2/launch/odom_ekf.launch.py
文件,输入以下内容
import os import launch import launch_ros def generate_launch_description(): package_name = 'fishbot_navigation2' ld = launch.LaunchDescription() pkg_share = launch_ros.substitutions.FindPackageShare(package=package_name).find(package_name) robot_localization_node = launch_ros.actions.Node( package='robot_localization', executable='ekf_node', name='ekf_filter_node', output='screen', parameters=[os.path.join(pkg_share, 'config/ekf.yaml'), {'use_sim_time': launch.substitutions.LaunchConfiguration('use_sim_time')}] ) ld.add_action(launch.actions.DeclareLaunchArgument(name='use_sim_time', default_value='True', description='Flag to enable use_sim_time')) ld.add_action(robot_localization_node) return ld
install(
DIRECTORY launch config param maps
DESTINATION share/${PROJECT_NAME}
)
colcon build --packages-select fishbot_navigation2
source install/setup.bash
ros2 launch fishbot_description gazebo.launch.py
source install/setup.bash
ros2 launch fishbot_navigation2 odom_ekf.launch.p
融合后的数据通过话题/odometry/filtered发布
ros2 topic echo /odometry/filtered
小鱼在仿真环境上测试了下,仿真中采用的里程计数据并不是轮子积分获取,而是通过gazebo直接获取的,所以当轮子打滑时并不会对里程计进行积分,所以测不出打滑时的效果,等fishbot完工后,在fishbot上做一下测试,看看效果如何。
这是小鱼第二年和大家一起过中秋了,祝各位鱼粉大家中秋快乐~
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。