文章目录

  • 1.软件的安装
    • 1.1.Ubuntu 22.04
    • 1.2.ROS2
    • 1.3.Gazebo
    • 1.4.MoveIt2
    • 1.5.moveit-setup-assistant
  • 2.机械手urdf文件的编写
    • 2.1.机械手的外型
    • 2.2.机械手link的inertial的设置
    • 2.3.ros2_control插件
  • 3.机械手与MoveIt的关联
    • 3.1.建立一个文件夹myRobot,然后再在此文件夹中建立一个src文件夹
    • 3.2.然后进入src文件夹路径,创建包
    • 3.3.在 src/mybot_description文件夹下,创建urdf文件夹,然后把six_arm.urdf放进去,如下图所示。
    • 3.4.返回myRobot目录,然后编译一下
    • 3.5.source一下
    • 3.6.利用moveit_setup_assistant创建项目
    • 3.7.编译试运行
  • 4.机械手与Gazebo的关联
    • 4.1.在 src/mybot/launch 路径下,新建一个文件: gazebo.launch.py
    • 4.2.将 src/mybot_description/urdf/six_arm.urdf 的内容修改一下
    • 4.3.编译、运行
    • 4.4. action send_goal 测试
  • 5.MoveIt与Gazebo的关联
    • 5.1.原理分析
    • 5.2.launch文件编写
    • 5.2.执行测试
  • 6.总结

目前的空余时间主要都在研究ROS2,最终目的是控制自己用舵机组装的机械手。
由于种种原因,先控制Gazebo的自定义机械手。
先看看目前的成果
左侧是rviz2中的moveit组件的机械手,右侧是gazebo中的机械手。在moveit中进行路径规划并执行后,右侧gazebo中的机械手也就执行相应的动作。

1.软件的安装

1.1.Ubuntu 22.04

据说win10下也可以装ROS2,但是十分折腾,还是在Ubuntu下安装方便一些,Ubuntu22.04才有humble版本的ros2,Ubuntu20.04没有humble。

1.2.ROS2

按照鱼香ros的教程,在命令行中执行鱼香ROS的一键安装代码

wget http://fishros.com/install -O fishros && . fishros

然后选择安装ros,选择humble版本。

1.3.Gazebo

参考教程
只要执行两行就行

#sudo apt install gazebo11 # 这样子会出现 E: Unable to locate package gazebo11 的问题
# 感谢评论区的指正
sudo apt install gazebo
sudo apt install ros-humble-gazebo-*

1.4.MoveIt2

参考教程
MoveIt2可以选择自己编译源码安装,或者直接从二进制安装。
个人建议直接二进制安装,可以省很多事。

sudo apt install ros-humble-moveit

1.5.moveit-setup-assistant

这是一个配套moveit的配置助手,有了它就可以方便地进行很多初始化的工作。

sudo apt install ros-humble-moveit-setup-assistant

顺便把别的东西也装了:

sudo apt install ros-humble-moveit-*

2.机械手urdf文件的编写

我们用urdf文件来描述我们的机械手的外观以及物理性能。这里为了简便,就只用了基本的圆柱、立方体了。追求美观的朋友,还可以用dae文件来描述机械手的外形。
文件six_arm.urdf

<?xml version="1.0"?>
<robot name="six_arm"><!-- Base link --><link name="base_link"><visual><geometry><box size="0.1 0.1 0.1"/></geometry><origin rpy="0 0 0" xyz="0 0 0.05"/><material name="blue"><color rgba="0 0 1.0 1"/></material></visual><collision><geometry><box size="0.1 0.1 0.1"/></geometry><origin rpy="0 0 0" xyz="0 0 0.05"/></collision><inertial><mass value="10"/><inertia ixx="0" ixy="0" ixz="0" iyy="0" iyz="0" izz="0"/></inertial></link><!-- Link 1 --><link name="link1"><visual><geometry><cylinder length="0.1" radius="0.03"/></geometry><origin rpy="0 0 0" xyz="0 0 0.05"/><material name="green"><color rgba="0 0.8 0 1"/></material></visual><collision><geometry><cylinder length="0.1" radius="0.03"/></geometry><origin rpy="0 0 0" xyz="0 0 0.05"/></collision><inertial><mass value="0.2"/><inertia ixx="0" ixy="0" ixz="0" iyy="0" iyz="0" izz="0"/></inertial></link><!-- Joint 1: rotation around X-axis --><joint name="joint1" type="continuous"><parent link="base_link"/><child link="link1"/><axis xyz="0 0 1"/><origin xyz="0 0 0.1" rpy="0 0 0"/></joint><!-- Link 2 --><link name="link2"><visual><geometry><cylinder length="0.1" radius="0.03"/></geometry><origin rpy="0 0 0" xyz="0 0 0.05"/><material name="red"><color rgba="0.8 0 0 1"/></material></visual><collision><geometry><cylinder length="0.1" radius="0.03"/></geometry><origin rpy="0 0 0" xyz="0 0 0.05"/></collision><inertial><mass value="0.2"/><inertia ixx="0" ixy="0" ixz="0" iyy="0" iyz="0" izz="0"/></inertial></link><!-- Joint 2: rotation around Y-axis --><joint name="joint2" type="continuous"><parent link="link1"/><child link="link2"/><axis xyz="1 0 0"/><origin xyz="0 0 0.1"/></joint><!-- Link 3 --><link name="link3"><visual><geometry><cylinder length="0.1" radius="0.03"/></geometry><origin rpy="0 0 0" xyz="0 0 0.05"/><material name="yellow"><color rgba="0.8 0.8 0 1"/></material></visual><collision><geometry><cylinder length="0.1" radius="0.03"/></geometry><origin rpy="0 0 0" xyz="0 0 0.05"/></collision><inertial><mass value="0.2"/><inertia ixx="0" ixy="0" ixz="0" iyy="0" iyz="0" izz="0"/></inertial></link><!-- Joint 3: rotation around x-axis --><joint name="joint3" type="continuous"><parent link="link2"/><child link="link3"/><axis xyz="1 0 0"/><origin xyz="0 0 0.1"/></joint><!-- Link 4 --><link name="link4"><visual><geometry><cylinder length="0.1" radius="0.03"/></geometry><origin rpy="0 0 0" xyz="0 0 0.05"/><material name="green"><color rgba="0 0.8 0 1"/></material></visual><collision><geometry><cylinder length="0.1" radius="0.03"/></geometry><origin rpy="0 0 0" xyz="0 0 0.05"/></collision><inertial><mass value="0.2"/><inertia ixx="0" ixy="0" ixz="0" iyy="0" iyz="0" izz="0"/></inertial></link><!-- Joint 4: rotation around X-axis --><joint name="joint4" type="continuous"><parent link="link3"/><child link="link4"/><axis xyz="0 1 0"/><origin xyz="0 0 0.1"/></joint><!-- Link 5 --><link name="link5"><visual><geometry><cylinder length="0.1" radius="0.03"/></geometry><origin rpy="0 0 0" xyz="0 0 0.05"/><material name="purple"><color rgba="0.8 0 0.8 1"/></material></visual><collision><geometry><cylinder length="0.1" radius="0.03"/></geometry><origin rpy="0 0 0" xyz="0 0 0.05"/></collision><inertial><mass value="0.2"/><inertia ixx="0" ixy="0" ixz="0" iyy="0" iyz="0" izz="0"/></inertial></link><!-- Joint 5: rotation around Y-axis --><joint name="joint5" type="continuous"><parent link="link4"/><child link="link5"/><axis xyz="1 0 0"/><origin xyz="0 0 0.1"/></joint><!-- Link 6 --><link name="link6"><visual><geometry><box size="0.1 0.1 0.2"/></geometry><origin rpy="0 0 0" xyz="0 0 0.1"/><material name="pink"><color rgba="0.8 0.4 0.8 1"/></material></visual><collision><geometry><box size="0.1 0.1 0.2"/></geometry><origin rpy="0 0 0" xyz="0 0 0.1"/></collision><inertial><mass value="0.2"/><inertia ixx="0" ixy="0" ixz="0" iyy="0" iyz="0" izz="0"/></inertial></link><!-- Joint 6: rotation around Z-axis --><joint name="joint6" type="continuous"><parent link="link5"/><child link="link6"/><axis xyz="0 0 1"/><origin xyz="0 0 0.1"/></joint><!-- Used for fixing robot to Gazebo 'base_link' 将机械手的基座固定在世界坐标上--><link name="world"/><joint name="fixed" type="fixed"><parent link="world"/><child link="base_link"/></joint><gazebo reference="base_link"><material>Gazebo/Black</material><gravity>true</gravity><selfCollide>false</selfCollide></gazebo><gazebo reference="link1"><material>Gazebo/Gray</material><selfCollide>false</selfCollide></gazebo><gazebo reference="link2"><material>Gazebo/Red</material><selfCollide>false</selfCollide></gazebo><gazebo reference="link3"><material>Gazebo/Blue</material></gazebo><gazebo reference="link4"><material>Gazebo/Green</material></gazebo><gazebo reference="link5"><material>Gazebo/Yellow</material></gazebo><gazebo reference="link6"><material>Gazebo/Orange</material></gazebo><!-- 在有需要时注释这个ros2_control节点--><ros2_control name="GazeboSystem" type="system"><hardware><plugin>gazebo_ros2_control/GazeboSystem</plugin></hardware><joint name="joint1"><command_interface name="position"><param name="min">-1</param><param name="max">1</param></command_interface><state_interface name="position"><param name="initial_value">0.0</param></state_interface><state_interface name="velocity"/></joint><joint name="joint2"><command_interface name="position"><param name="min">-1</param><param name="max">1</param></command_interface><state_interface name="position"><param name="initial_value">0.0</param></state_interface><state_interface name="velocity"/></joint><joint name="joint3"><command_interface name="position"><param name="min">-1</param><param name="max">1</param></command_interface><state_interface name="position"><param name="initial_value">0.0</param></state_interface><state_interface name="velocity"/></joint><joint name="joint4"><command_interface name="position"><param name="min">-1</param><param name="max">1</param></command_interface><state_interface name="position"><param name="initial_value">0.0</param></state_interface><state_interface name="velocity"/></joint><joint name="joint5"><command_interface name="position"><param name="min">-1</param><param name="max">1</param></command_interface><state_interface name="position"><param name="initial_value">0.0</param></state_interface><state_interface name="velocity"/></joint><joint name="joint6"><command_interface name="position"><param name="min">-1</param><param name="max">1</param></command_interface><state_interface name="position"><param name="initial_value">0.0</param></state_interface><state_interface name="velocity"/></joint></ros2_control><gazebo><plugin filename="libgazebo_ros2_control.so" name="gazebo_ros2_control"><parameters>/home/yong/Desktop/myRobot/src/mybot/config/ros2_controllers.yaml</parameters><robot_param_node>robot_state_publisher</robot_param_node></plugin></gazebo></robot>

2.1.机械手的外型

可以在vscode中打开这个文件然后用插件就可以看到这个机械手的外形,关于urdf语法的详细介绍,可以看这里。
有同学不知道如何在vscode中查看urdf模型,这里介绍一下:
先安装vscode的ROS拓展,
然后可以在urdf文件中右键–》command palette–》ROS:Preview URDF

2.2.机械手link的inertial的设置

我这里偷懒,随便设置的。真正设置的话,有公式,自己可以参考一下。
urdf里面的link必须要有旋转惯量矩阵‘intertial’的,否则在gazebo里面导入模型urdf时,会报下面的错。
[gazebo-1] [Err] [Model.cc:123] Error Code 23 Msg: FrameAttachedToGraph error, Non-LINK vertex with name [model] is disconnected; it should have 1 outgoing edge in MODEL attached_to graph.

2.3.ros2_control插件

该插件是在gazbo导入该模型文件时,创建与Ros2交互的接口。

上面的ros2_controllers.yaml文件是在下一步创建出来的,先不用管。
同时,ros2_control这个节点下的内容也是要和ros2_controllers.yaml对应的,也可以先不管。
这个节点在开始阶段先注释掉,否则会与通过moveit_setup_assistant创建的一个 fake_system 的 ros2_control冲突。

3.机械手与MoveIt的关联

通过前面的操作,我们拥有了一个描述机械手的文件 six_arm.urdf,接下来我们利用该文件创建一个可以利用MoveIt进行路径规划的“工程”。

3.1.建立一个文件夹myRobot,然后再在此文件夹中建立一个src文件夹

3.2.然后进入src文件夹路径,创建包

ros2 pkg create mybot_description --build-type ament_python

3.3.在 src/mybot_description文件夹下,创建urdf文件夹,然后把six_arm.urdf放进去,如下图所示。

3.4.返回myRobot目录,然后编译一下

colcon build

3.5.source一下

source的目的是为了把我们创建的 mybot_description项目暴露给控制台,然后让后续的moveit_setup_assistant可以找到对应的urdf文件

source install/setup.bash

3.6.利用moveit_setup_assistant创建项目

参考教程,启动moveit_setup_assistant

 ros2 run moveit_setup_assistant moveit_setup_assistant

记得选择src里面的urdf,然后后面的就按照教程来干了。
注意:group name设置my_group
一些关键的设置看下列图

在最后一步保存时,在我们前面创建的src文件夹里面,创建一个mybot文件夹
然后在助手里选择该路径,点击generat package

3.7.编译试运行

此时,退出助手,并执行编译;
编译完成后,重新source一下。

colcon build
source install/setup.bash


记得把前面的urdf文件里面的这个路径改成你自己的。
这段注释一下,否则会有冲突。到后面就可以取消注释,但是目前要注释掉。

每次修改完文件后,记得都要 colcon build一下。

试着执行

ros2 launch mybot demo.launch.py

会报错

这是因为在编译时没有把urdf文件拷贝到install目录中,因此我们需要修改一下 src/mybot_description/setup.py
修改三处地方,将其修改成类似下面这样
修改完之后就可以自动在编译时复制到install目录了,具体原理可以自己按照代码推测一下

from setuptools import setupfrom glob import glob #这里
import os #这里package_name = 'mybot_description'setup(name=package_name,version='0.0.0',packages=[package_name],data_files=[('share/ament_index/resource_index/packages',['resource/' + package_name]),('share/' + package_name, ['package.xml']),(os.path.join('share', package_name, 'urdf'), glob('urdf/**')), #这里],install_requires=['setuptools'],zip_safe=True,maintainer='yong',maintainer_email='yong@todo.todo',description='TODO: Package description',license='TODO: License declaration',tests_require=['pytest'],entry_points={'console_scripts': [],},
)

colcon build一下。
然后启动

ros2 launch mybot demo.launch.py

然后就可以愉快地玩耍了。

假如报其他错误请查看此处。

4.机械手与Gazebo的关联

gazebo相关执行文件的写法,我是参考了gazebo的例程【/opt/ros/humble/share/gazebo_ros2_control_demos下面的launch、urdf(xacro)】写的,各位也可以去看看分析一下,能了解到不少知识。

4.1.在 src/mybot/launch 路径下,新建一个文件: gazebo.launch.py

其内容如下

import os
from launch import LaunchDescription
from launch.actions import ExecuteProcess, RegisterEventHandler
from launch_ros.actions import Node
from launch_ros.substitutions import FindPackageSharefrom launch.event_handlers import OnProcessExitdef generate_launch_description():robot_name_in_model = 'six_arm'package_name = 'mybot_description'urdf_name = "six_arm.urdf"pkg_share = FindPackageShare(package=package_name).find(package_name) urdf_model_path = os.path.join(pkg_share, f'urdf/{urdf_name}')# Start Gazebo serverstart_gazebo_cmd =  ExecuteProcess(cmd=['gazebo', '--verbose','-s', 'libgazebo_ros_init.so', '-s', 'libgazebo_ros_factory.so'],output='screen')# Launch the robotspawn_entity_cmd = Node(package='gazebo_ros', executable='spawn_entity.py',arguments=['-entity', robot_name_in_model,  '-file', urdf_model_path ], output='screen')node_robot_state_publisher = Node(package='robot_state_publisher',executable='robot_state_publisher',arguments=[urdf_model_path],parameters=[{'use_sim_time': True}],output='screen')# 关节状态发布器load_joint_state_controller = ExecuteProcess(cmd=['ros2', 'control', 'load_controller', '--set-state', 'active','joint_state_broadcaster'],output='screen')# 路径执行控制器load_joint_trajectory_controller = ExecuteProcess(cmd=['ros2', 'control', 'load_controller', '--set-state', 'active','my_group_controller'],output='screen')close_evt1 =  RegisterEventHandler( event_handler=OnProcessExit(target_action=spawn_entity_cmd,on_exit=[load_joint_state_controller],))close_evt2 = RegisterEventHandler(event_handler=OnProcessExit(target_action=load_joint_state_controller,on_exit=[load_joint_trajectory_controller],))ld = LaunchDescription()ld.add_entity(close_evt1)ld.add_entity(close_evt2)ld.add_action(start_gazebo_cmd)ld.add_action(node_robot_state_publisher)ld.add_action(spawn_entity_cmd)return ld

4.2.将 src/mybot_description/urdf/six_arm.urdf 的内容修改一下

将这一段取消注释。

4.3.编译、运行

每次修改完文件后,记得都要 colcon build一下。
colcon build一下。
然后启动

ros2 launch mybot gazebo.launch.py

然后就可以愉快地玩耍了。

4.4. action send_goal 测试

目前运行的这这个gazebo例子已经开放了一个action接口,通过这个接口,我们就可以直接发送一个路径让其执行。

我们可以手写一个轨迹,然后让其执行
新建一个my_send_goal.sh文件,然后通过 chmod +x 使其具有执行权限


文件内容如下:

ros2 action send_goal /my_group_controller/follow_joint_trajectory control_msgs/action/FollowJointTrajectory "{trajectory: {joint_names: [joint1, joint2, joint3, joint4, joint5, joint6],points: [{ positions: [0.1, 0.1, 0.1, 0.1, 0.1, 0.1], time_from_start: { sec: 0, nanosec: 500 } },{ positions: [0.2, 0.5, 0.2 ,0.2, 0.2, 0.2], time_from_start: { sec: 5, nanosec: 500 } },{ positions: [0.3, 0.3, 0.7, -0.5, 0.3, 0.3], time_from_start: { sec: 7, nanosec: 500 } },{ positions: [0.4, 0.4, 0.9, 0.4, 0.4, 0.4], time_from_start: { sec: 8, nanosec: 500 } }]}
}"

然后在控台里面执行

./my_send_goal.sh

接下来可以看到gazebo中的机械手按照我们设定的轨迹进行运动了。
可以尝试改变一下my_send_goal.sh 的内容,然后推测一下各个参数的意义。

5.MoveIt与Gazebo的关联

moveit提供了路径规划接口,gazebo提供了执行接口,因此只需要将他们连起来就实现了路径规划仿真了。

5.1.原理分析

在前面通过moveit_setup_assistant创建的包中,之所以可以进行路径规划并执行,是因为他既启动了moveit的组件,也启动了一个FakeSystem节点,该节点代替了实际的机械手反馈moveit的路径规划(提供action给moveit连接)。

从下图可以看出,当我们执行demo时,有好几个节点启动了。

但是假如我们需要将FakeSystem节点替换成gazebo的节点,就可以通过只启动需要的几个节点,然后不启动FakeSystem就行。

5.2.launch文件编写

按照5.1的分析,我们可以在src/mybot/launch下新建一个文件my_moveit_rviz.launch.py,
文件内容为

from moveit_configs_utils import MoveItConfigsBuilder
from moveit_configs_utils.launches import generate_moveit_rviz_launchfrom launch import LaunchDescription
from launch.actions import (DeclareLaunchArgument,IncludeLaunchDescription,
)
from moveit_configs_utils.launch_utils import (add_debuggable_node,DeclareBooleanLaunchArg,
)
from launch.substitutions import LaunchConfiguration
from launch_ros.parameter_descriptions import ParameterValuedef generate_launch_description():moveit_config = MoveItConfigsBuilder("six_arm", package_name="mybot_description").to_moveit_configs()ld = LaunchDescription()# 启动move_groupmy_generate_move_group_launch(ld, moveit_config)# 启动rvizmy_generate_moveit_rviz_launch(ld, moveit_config)return lddef my_generate_move_group_launch(ld, moveit_config):ld.add_action(DeclareBooleanLaunchArg("debug", default_value=False))ld.add_action(DeclareBooleanLaunchArg("allow_trajectory_execution", default_value=True))ld.add_action(DeclareBooleanLaunchArg("publish_monitored_planning_scene", default_value=True))# load non-default MoveGroup capabilities (space separated)ld.add_action(DeclareLaunchArgument("capabilities", default_value=""))# inhibit these default MoveGroup capabilities (space separated)ld.add_action(DeclareLaunchArgument("disable_capabilities", default_value=""))# do not copy dynamics information from /joint_states to internal robot monitoring# default to false, because almost nothing in move_group relies on this informationld.add_action(DeclareBooleanLaunchArg("monitor_dynamics", default_value=False))should_publish = LaunchConfiguration("publish_monitored_planning_scene")move_group_configuration = {"publish_robot_description_semantic": True,"allow_trajectory_execution": LaunchConfiguration("allow_trajectory_execution"),# Note: Wrapping the following values is necessary so that the parameter value can be the empty string"capabilities": ParameterValue(LaunchConfiguration("capabilities"), value_type=str),"disable_capabilities": ParameterValue(LaunchConfiguration("disable_capabilities"), value_type=str),# Publish the planning scene of the physical robot so that rviz plugin can know actual robot"publish_planning_scene": should_publish,"publish_geometry_updates": should_publish,"publish_state_updates": should_publish,"publish_transforms_updates": should_publish,"monitor_dynamics": False,}move_group_params = [moveit_config.to_dict(),move_group_configuration,]move_group_params.append({"use_sim_time": True})add_debuggable_node(ld,package="moveit_ros_move_group",executable="move_group",commands_file=str(moveit_config.package_path / "launch" / "gdb_settings.gdb"),output="screen",parameters=move_group_params,extra_debug_args=["--debug"],# Set the display variable, in case OpenGL code is used internallyadditional_env={"DISPLAY": ":0"},)return lddef my_generate_moveit_rviz_launch(ld, moveit_config):"""Launch file for rviz"""ld.add_action(DeclareBooleanLaunchArg("debug", default_value=False))ld.add_action(DeclareLaunchArgument("rviz_config",default_value=str(moveit_config.package_path / "config/moveit.rviz"),))rviz_parameters = [moveit_config.planning_pipelines,moveit_config.robot_description_kinematics,]rviz_parameters.append({"use_sim_time": True})add_debuggable_node(ld,package="rviz2",executable="rviz2",output="log",respawn=False,arguments=["-d", LaunchConfiguration("rviz_config")],parameters=rviz_parameters,)return ld

在文件中,我们主要启动了两个节点:move_group、rviz。
这里面这还涉及到一个use_sim_time的问题,因此才这样重写。参考这里
然后colcon build一下。

5.2.执行测试

分别打开两个控制台,然后分别执行以下命令

ros2 launch mybot gazebo.launch.py
ros2 launch mybot my_moveit_rviz.launch.py


注意是要先运行gazebo(ros2 launch mybot gazebo.launch.py),然后再运行moveit(ros2 launch mybot my_moveit_rviz.launch.py )
在moveit里面规划路径、然后执行。
在gazebo就可以看到模型动了起来。

6.总结

目前只是通过大致的操作完成了moveit控制gazebo里面的机械手,是偏操作方面的,原理可以粗略地理解成action的通讯。至于更加详细以及深入的教程,就等各位大佬来完成了。

在ROS2中,通过MoveIt2控制Gazebo中的自定义机械手相关推荐

  1. unity中通过代码控制游戏中画质

    最近在开发项目的时候突然想到可以添加一个调整画质的按钮或者DropDown或者Slider的UI来控制游戏中的画质 因为我之前写过一篇关于DropDown的使用方法的博客 DropDown的使用方法地 ...

  2. Spring中的事务控制学习中

    Chapter 1. Spring中的事务控制(Transacion Management with Spring) Table of Contents 事务管理(Transaction Manage ...

  3. Spring中的事务控制学习中(转)

    1.1. 有关事务(Transaction)的楔子 1.1.1. 认识事务本身 1.1.2. 初识事务家族成员 1.2. 群雄逐鹿下的Java事务管理 1.2.1. Java平台的局部事务支持 1.2 ...

  4. java中的流程控制_Java中的流程控制

    1.break和continue break用于强行推出循环,不执行循环中剩余的语句.continue用于停止执行当前的迭代,然后退回循环起始处,开始下一次迭代.看下面的代码: public clas ...

  5. ROS2中用MoveIt2控制自己的舵机机械手(5)

    1.前言 在上一篇[ROS2中用MoveIt2控制自己的舵机机械手(4)],我们已经实现了上下位机的通讯.由于目前使用的是舵机,MCU(stm32)是无法从舵机那里读取到当前的角度的,因此下位机发给上 ...

  6. 使用MATLAB绘制Gazebo中的仿真小车的运动轨迹

       虽然,Gazebo中自带了绘图工具,当需要绘制一些简单的图像时,非常的方便,但是当需要绘制复杂的图像时,还是MATLAB更加合适一些.    当我们仅仅使用MATLAB以可视化图像的形式去观察G ...

  7. TIANBOT MINI机器人在gazebo中使用键盘控制运动

    在上一节,我们配置好了xacro文件,那么这一节我们实现小车在gazebo环境中通过键盘控制节点动起来,并且使用rviz可视化工具. 01 配置各个文件 第一步首先是要修改描述文件,修改的目的是增加c ...

  8. Universal Robot——在Gazebo中模拟UR5机器人

    今天的目标是在Gazebo安装我们的ur5机器人.Gazebo是一个流行的模拟工具,它不仅可以让你像在Rviz中一样可视化你的机器人,而且还内置了一个物理引擎.这样你就可以在更真实的环境中测试你的机器 ...

  9. gazebo中给机器人添加16线激光雷达跑LIO-SAM

    目录: 前言 1.下载雷达仿真包 2.添加雷达支架描述文件 3.添加雷达描述文件 4.启动仿真 5.添加IMU模块 6.添加RGB-D相机 7.LIO-SAM仿真 安装依赖 安装GTSAM 编译LIO ...

最新文章

  1. SMRT测序技术及其在微生物研究中的应用
  2. 网络推广外包专员浅析网络推广外包优化当中的那些细枝末节!
  3. WEB打印大全(转)
  4. mysql5.6英文版安装步骤_mysql5.6版本安装步骤详解
  5. 交叉驰豫的影响因素_交叉滚子轴承系列吉林薄壁交叉滚子轴承用途博盈
  6. 【angularjs】使用angular搭建项目,pc端实现网页中的内容不可复制
  7. 【渝粤教育】国家开放大学2019年春季 1171科学与技术 参考试题
  8. 你可能不需要 Vuex
  9. 【LeetCode】【HOT】581. 最短无序连续子数组
  10. POJ3420 Quad Tiling【矩阵快速幂】
  11. 阿里云HBase产品体系架构及特性解析
  12. 简单的C语言代码实现快速排序
  13. Linux服务器 mysql5.7安装流程
  14. 第一次给笔记本换固态硬盘
  15. 计算机系统兼容在哪里,电脑怎么看系统兼容的
  16. U的含义,u是什么单位
  17. mybatis like的两种写法
  18. VirtualBox虚拟电脑控制台错误,不能为虚拟电脑打开一个新任务
  19. unity访问其他游戏对象的四种方式
  20. visual怎么运行python_Visual Studio运行Python程序(超级详细)

热门文章

  1. 关于三点演讲与口才训练方法
  2. 计算机软考网络工程师难度大吗,国家软考的网络工程师与CCNP相比,哪个难?...
  3. 项目需求分析和项目可行性
  4. 我的2018:用一年的时间写一份年终总结!
  5. jenkins构建时,从国内maven私服下载jar包失败
  6. DasBlog: 构建一个分布式.NET 协作系统
  7. python撩妹小技巧 —— 30行代码实现520小彩蛋
  8. 熔断器Hystrix
  9. 淘宝用户购物行为分析
  10. chart.js-折线图