ROS

睿尔曼超轻量仿人机械臂--睿尔曼 RM65-B 机器人 ROS 使用说明书 V1.6

Forrest 2023-11-25

 

1.package介绍

 

2.环境要求

       系统:Ubuntu 18.04或Ubuntu 20.04
       其余软件要求:Moveit!已安装;Gazebo可用;ros_control插件可用
       ROS:melodic或noetic

3.源码安装编译

 新建名称为ws_rmrobot的工作空间,执行如下命令:

mkdir -p ~/ws_rmrobot/src
cd ~/ws_rmrobot/src/
然后将提供的rm_robot源码包拷贝到ws_rmrobot工作空间的src目录下或将源码包拷贝到自己创建的其他工作空间的src目录下:
 
图3-1 将rm_robot源码包拷贝到ws_rmrobot/src下
通过rosdep安装源码包依赖,执行以下命令(若为ROS Noetic版本则将命令中的melodic改为noetic):
rosdep install -y --from-paths . --ignore-src --rosdistro melodic -r 
使用catkin工具配置工作空间并进行编译,执行如下命令:
cd ~/ws_rmrobot
catkin init
catkin build rm_msgs
catkin build
编译完成如下图所示:
 
图3-2 rm_robot源码包编译成功

4.在rviz中显示机械臂模型

4.1机器人描述功能包

在rm_robot源码包中包含了rm_65_description功能包,其中有创建好的机器人模型和配置文件。
rm_65_description功能包中主要包含urdf、meshes、launch和config四个文件夹。
urdf:用于存放机器人模型的URDF或xacro文件。
meshes:用于放置URDF中引用的模型渲染文件。
launch:用于存放相关启动文件。
config:用于保存rviz的配置文件。

4.2在rviz中显示模型

rm_65_description/launch/display_rm65.launch, 在rm_65_description功能包launch文件夹中已经创建用于显示rm_65模型的launch文件 。                           
打开终端进入工作空间执行以下命令运行该launch文件:
cd ~/ws_rmrobot
source devel/setup.bash
roslaunch rm_65_description display.launch
如果一切正常,可以在打开的rviz中看到如图4-1所示的机器人模型。
图4-1 在rviz中显示RM65-B机械臂模型
运行成功后,不仅启动了rviz,而且出现了一个名为“joint_state_publisher”的UI。这是因为我们在启动文件中启动了joint_state_publisher节点,该节点可以发布每个joint(除fixed类型)的状态,而且可以通过UI对joint进行控制。所以在控制界面中用鼠标滑动控制条,rviz中对应的机械臂关节就会转动。
如果rviz中未显示模型,则手动修改“Fixed Frame”为“base_link”,然后点击左侧下方的Add按钮在弹出的界面中找到“RobotModel”添加即可,如图4-2~4-3所示:
 
图4-2 修改FixedFrame为base_link
图4-3 rviz中添加RobotModel

5.启动MoveIt!

5.1MoveIt!简介

在实现机械臂的自主抓取中机械臂的运动规划是其中最重要的一部分,其中包含运动学正逆解算、碰撞检测、环境感知和动作规划等。常见机械臂的运动规划大都采用的是ROS系统提供的MoveIt! 规划。
MoveIt! 是ROS系统中集合了与移动操作相关的组件包的运动规划库。它包含了运动规划中所需要的大部分功能,同时其提供友好的配置和调试界面便于完成机器人在ROS系统上的初始化及调试。
官方网站:http://moveit.ros.org/,上边有MoveIt!的教程和API说明。

5.2安装MoveIt!

MoveIt!需要安装才能使用,如果未安装,请执行如下命令进行安装(若为ROS Noetic版本则将命令中的melodic 改为noetic)。
sudo apt install ros-melodic-moveit
sudo apt install ros-melodic-moveit-*

5.3运行RM65-B机械臂的MoveIt!演示demo

在rm_robot源码包中包含了rm_65_moveit_config功能包,它是使用Setup Assistant工具根据机械臂URDF模型创建 生成的一个MoveIt!配置的功能包,它包含了大部分MoveIt!启动所需的配置文件和启动文件,以及包含一个简单的演示demo。
打开终端进入工作空间执行以下命令运行RM65-B机械臂的MoveIt!演示demo:
cd ~/ws_rmrobot
source devel/setup.bash
roslaunch rm_65_moveit_config demo.launch

启动成功后,可以看到如图5-1所示的界面。

图5-1 MoveIt! demo的启动界面
这个界面在rviz的基础上加入了MoveIt!插件,通过左下角的插件窗口可以配置MoveIt!的相关功能,控制机械臂完成运动规划。例如通过MoveIt!插件,可以控制机械臂完成拖动规划、随机目标规划、初始位姿更新、碰撞检测等功能。
5.3.1拖动规划
拖动机械臂的前端,可以改变机械臂的姿态。然后在Planning标签页中点击“Plan & Execute”按钮,MoveIt!开始规划路径,并且控制机器人向目标位置移动,从右侧界面可以看到机器人运动的全部过程(见图5-2)。
图5-2 拖动规划的运动效果
5.3.2选择目标姿态规划
在Planning标签页中点击Goal State的下拉列表可以选择机械臂的目标姿态,然后点击“Plan & Execute”按钮,MoveIt!开始规划路径,并且控制机器人向目标位置移动,从右侧界面可以看到机器人运动的全部过程(见图5-3)。
图5-3 选择目标姿态规划的运动效果

6.使用MoveIt!控制Gazebo中的机械臂

6.1概述

MoveIt!与Gazebo的联合仿真,其主要思路为搭建ros_control和MoveIt!的桥梁。先在MoveIt!端配置关节和传感器接口yaml文件,将其加载到rviz端;再在机器人端配置ros_control和接口yaml文件,将机器人加载到Gazebo。最后同时启动加载有ros_control的Gazebo和加载有MoveIt的rviz,达到联合仿真的目的。
6.2配置说明
6.2.1 MoveIt!端的配置
1)控制器配置文件controllers_gazebo.yaml
controllers_gazebo.yaml在rm_65_moveit_config/config目录下,代码如下:
controller_manager_ns: controller_manager
controller_list:
  - name: arm/arm_joint_controller
    action_ns: follow_joint_trajectory
    type: FollowJointTrajectory
    default: true
    joints:
      - joint1
      - joint2
      - joint3
      - joint4
      - joint5
      - joint6
2)修改启动文件rm_65_moveit_controller_manager.launch.xml
修改rm_65_moveit_config功能包中的rm_65_moveit_controller_manager.launch.xml,配置加载刚才创建的controllers_gazebo.yaml文件到参数服务器,代码如下:


 



 



 




3)启动文件moveit_planning_execution.launch
moveit_planning_execution.launch是在rm_65_moveit_config/launch目录下新创建的启动文件,用以加载MoveIt和rviz,最后运行关节状态发布器,用以向Gazebo中发布指令,代码如下:

 # The planning and execution components of MoveIt! configured to
 # publish the current configuration of the robot (simulated or real)
 # and the current state of the world as seen by the planner
 
  
 
 
 # The visualization component of MoveIt!
 
 
  
  
    
    [/arm/joint_states]
  

6.2.2机器人端的配置
关节轨迹控制器
MoveIt!完成运动规划后的输出接口是一个命名为“FollowJointTrajectory”的action,其中包含了一系列规划好的路径点轨迹,这些信息可以通过ros_control为我们提供的一个名为“Joint Trajectory Controller”的控制器插件转换成Gazebo中机器人需要的joint位置。
1)配置文件rm_65_trajectory_control.yaml
“FollowJointTrajectory”控制器的使用首先需要一个配置文件对机械臂六个轴的轨迹控制配置控制参数,即rm_gazebo/config目录下的rm_65_trajectory_control.yaml配置文件,代码如下:
arm:
  arm_joint_controller:
    type: "position_controllers/JointTrajectoryController"
    joints:
      - joint1
      - joint2
      - joint3
      - joint4
      - joint5
      - joint6
    gains:
      joint1:   {p: 1000.0, i: 0.0, d: 0.1, i_clamp: 0.0}
      joint2:   {p: 1000.0, i: 0.0, d: 0.1, i_clamp: 0.0}
      joint3:   {p: 1000.0, i: 0.0, d: 0.1, i_clamp: 0.0}
      joint4:   {p: 1000.0, i: 0.0, d: 0.1, i_clamp: 0.0}
      joint5:   {p: 1000.0, i: 0.0, d: 0.1, i_clamp: 0.0}
      joint6:   {p: 1000.0, i: 0.0, d: 0.1, i_clamp: 0.0}
2)控制器启动文件
通过一个launch文件加载Joint Trajectory Controller,即rm_gazebo/launch目录下的arm_65_trajectory_controller.launch文件,代码如下:

 

    

    

          output="screen" ns="/arm" args="arm_joint_controller"/>

 

关节状态控制器
关节状态控制器是一个可选插件,主要作用是发布机器人的关节状态和TF变换,否则在rviz的Fixed Frame设置中看不到下拉列表中的坐标系选项,只能手动输入,但是依然可以正常使用。
1)关节状态控制器配置文件arm_gazebo_joint_states.yaml
arm_gazebo_joint_states.yaml配置文件在rm_gazebo/config目录下,代码如下:
arm:
  # Publish all joint states -----------------------------------
  joint_state_controller:
    type: joint_state_controller/JointStateController
    publish_rate: 50  
2)启动文件arm_gazebo_states.launch加载参数
arm_gazebo_states.launch文件在rm_gazebo/launch目录下,代码如下:
   

    

    

    

          output="screen" ns="/arm" args="joint_state_controller" />

    

    

        respawn="false" output="screen">

        

    

 

   
6.2.3启动文件arm_65_bringup_moveit.launch
顶层启动文件arm_65_bringup_moveit.launch在rm_gazebo/launch目录下,用以启动Gazebo,并且加载所有的控制器,最后启动MoveIt!,代码如下:

 

    

    

    

       

    

    

    

    

 

                          
6.3运行效果
启动节点前,需要确保rm_65_moveit_config/launch/rm_65_moveit_controller_manager.launch.xml文件中配置加载到参数服务器的是controllers_gazebo.yaml文件,见图6-1:
 
图6-1 rm_65_moveit_controller_manager.launch.xml加载controllers_gazebo.yaml
执行以下命令运行MoveIt!和Gazebo:
cd ~/ws_rmrobot
source devel/setup.bash
roslaunch rm_gazebo arm_65_bringup_moveit.launch
启动后打开的Gazebo如图6-2所示:
 
图6-2 RM65-B机器人在Gazebo中显示效果
启动后打开的rviz如图6-3所示:
图6-3 rviz启动界面
在打开的rviz中,暂时还看不到任何机器人模型,甚至还会提示一些错误,接下来进行简单配置解决这些问题。
首先将“Fixed Frame”修改成“base_link”;然后点击左侧插件列表栏中的“Add”按钮,将MotionPlanning加入控制窗口。此时应该可以看到机器人出现在右侧主界面中,Gazebo中机器人的姿态应该和rvize中的显示一致。操作如图6-4~6-6所示:
图6-4 在rviz中将“Fixed Frame”修改成“base_link”

图6-5 rviz中将MotionPlanning加入控制窗口

图6-6 rviz中显示RM65-B机器人
接下来使用MoveIt!规划运动的几种方式就可以控制Gazebo中的机器人了,例如图6-7拖动机器人末端到一个位置,然后点击“Plan & Execute”按钮,可以看到rviz中机器人开始规划执行并且可以看到Gazebo中的机器人开始运动且与rviz中的机器人模型保持一致,如图6-8所示。
图6-7 使用MoveIt!拖动规划执行

 
图6-8 Gazebo中机器人按rviz规划同步执行效果

7.使用MoveIt!控制真实机械臂

7.1概述

MoveIt!完成运动规划后的输出接口是一个命名为“FollowJointTrajectory”的action,其中包含了一系列规划好的路径点轨迹,与使用MoveIt!控制Gazebo中的机械臂不同的是,虚拟机械臂有gazebo的ros_control插件自动帮我们获取了follow_joint_trajectory的动作action信息,而现在到真实机器人,需要我们自己编程添加一个server订阅这个action并处理然后控制真实机器人。
7.1.1机器人控制器rm_control
机器人控制器rm_control功能包,通过添加一个server订阅MoveIt!完成运动规划后输出的action信息,然后将Moveit规划的机械臂轨迹,通过三次样条插值细分,按照20ms的控制周期发给rm_driver节点。具体实现见源码。
 
7.1.2机器人驱动功能包rm_driver
rm_driver功能包,实现与机械臂通过以太网口建立socket连接,订阅和发布机器人的各topic信息,将rm_control处理后发来的机械臂运行路径点轨迹通过socket发送至真实机械臂实现对真实机械臂的控制,同时接收机械臂返回的信息处理后通过topic发布至move_group完成rviz中机器人的同步。具体实现见源码。
7.1.3 rm_msgs功能包
rm_msgs功能包定义了RM65-B机器人所用到的所有控制消息和状态消息,rm_control和rm_driver都需要使用。
7.2运行演示
在运行前,先将RM65-B机器人上电,等待30秒让机器人完成初始化;
确保上位机IP与机械臂在同一局域网内,然后可以在终端执行:
ping 192.168.1.18
如果能ping通则可以继续以下操作;
修改rm_65_moveit_config/launch/rm_65_moveit_controller_manager.launch.xml,配置加载controllers.yaml文件到参数服务器,代码如下:


 



 



 



打开终端,执行以下命令先运行rm_control节点:
cd ~/ws_rmrobot/
source devel/setup.bash
roslaunch rm_control rm_control.launch
然后再打开一个新的终端,执行以下命令启动rm_driver节点和加载MoveIt!的rviz:
cd ~/ws_rmrobot/
source devel/setup.bash
roslaunch rm_bringup rm_robot.launch
运行成功后在rviz中可以看到机器人模型与真实机械臂的状态保持一致,如图7-1和7-2所示:
图7-1 真实机械臂状态

图7-2 rviz中机械臂模型状态与真实机械臂保持一致
在rviz中进行拖动规划然后点击“Plan & Execute”按钮,可以看到真实机械臂会按照rviz中MoveIt!规划的路径运动,如图7-3和7-4所示。
图7-3 rviz中机械臂模型规划路径运行到指定位置

图7-4 真实机械臂按照rviz中MoveIt!规划的路径运动到相同位置

8.MoveIt!编程示例---场景规划

8.1概述

在实际应用中,MoveIt! GUI提供的功能有限,很多实现需要在代码中完成。MoveIt!的move_group也提供了丰富的C++和Python的编程API,可以帮助我们完成更多运动控制的相关功能。
8.2实现功能
1)在场景中添加和移除物体
2)为机器人附加和拆卸物体
该程序源代码:rm_65_demo/src/planning_scene_ros_api_demo.cpp,具体实现见注释。
8.3运行演示
首先打开终端,执行以下命令运行MoveIt!演示demo:
cd ~/ws_rmrobot/
source devel/setup.bash
roslaunch rm_65_moveit_config demo.launch
rviz启动后如图8-1所示:
 
图8-1 MoveIt!演示demo界面
因为本示例程序使用MoveItVisualTools插件控制程序运行,所以需要在rviz中添加RvizVisualToolsGui插件,添加操作如图8-2~8-4所示:
图8-2 rviz中Add New Panel
 

图8-3 rviz中添加RvizVisualToolsGui
 

图8-4 rviz中添加RvizVisualToolsGui完成
打开一个新的终端,执行以下命令启动场景规划节点:
cd ~/ws_rmrobot/
source devel/setup.bash
roslaunch rm_65_demo planning_scene_ros_api_demo.launch
场景规划节点启动完成后提示点击rviz中RvizVisualToolsGui面板中的Next按钮开始运行程序,如图8-5所示:
 
图8-5场景规划节点启动完成等待交互运行
 
在rviz中点击RvizVisualToolsGui面板中的Next按钮可以看到,在机器人的末端位置添加了一个绿色物体,说明在场景中添加物体成功,如图8-6所示:
 
图8-6场景添加物体
再次点击Next按钮,可以看到物体改变了颜色,此时代表该物体被附加到了机器人上,在进行运动规划时会被视为是机器人的一部分检测碰撞,如图8-7所示:
图8-6物体被附加到机器人上
再次点击Next按钮,可以看到物体又变为了绿色,表示附着的物体从机器人上被解除附着,如图8-7所示:
图8-7附着物体被解除附着
再次点击Next按钮,可以看到物体消失了,说明物体从场景中被移除了,如图8-8所示:
图8-8物体从场景中移除
再次点击Next按钮,场景规划节点运行结束并退出,如图8-9所示:
图8-9场景规划节点运行结束退出

9.MoveIt!编程示例---避障规划

9.1概述

本示例源码为Python代码,调用了MoveIt!的move_group提供的Python API实现,源代码位置:rm_65_demo/scripts/moveit_obstacles_demo.py,具体实现见代码注释。
9.2实现功能
首先让机器人运动到已经配置好的“zero”位姿,然后在场景中添加一个table物体表示障碍物,再然后让机器人自动避开障碍物运动到“forward”位姿,最后再让机器人自动避开障碍物回到“zero”位姿。
9.3运行演示
首先打开终端,执行以下命令运行MoveIt!演示demo:
cd ~/ws_rmrobot/
source devel/setup.bash
roslaunch rm_65_moveit_config demo.launch
rviz启动后如图9-1所示:
 
图9-1 MoveIt!演示demo界面
再打开一个新的终端,执行以下命令启动避障规划节点:
cd ~/ws_rmrobot/
source devel/setup.bash
rosrun rm_65_demo moveit_obstacles_demo.py
节点运行后,在rviz中可以看到场景中添加了一个table物体,然后机器人自动避开table运行到forward位姿,最后从forward位姿自动避开table回到zero位姿,如图9-2所示:
图9-2 机器人自主避障效果

10.MoveIt!编程示例---pick and place

10.1概述

本示例源码为C++代码,调用了MoveIt!的move_group提供的C++ API实现,源代码位置:rm_65_demo/src/pick_place_demo.cpp,具体实现见代码注释。

10.2实现功能

模拟机械臂自动抓取物体然后进行运动规划将物体放置到指定位置。

10.3运行演示

首先打开终端,执行以下命令运行MoveIt!演示demo:
cd ~/ws_rmrobot/
source devel/setup.bash
roslaunch rm_65_moveit_config demo.launch
rviz启动后如图10-1所示:
 
图10-1 MoveIt!演示demo界面
再打开一个新的终端,执行以下命令运行pick_place_demo节点:
cd ~/ws_rmrobot/
source devel/setup.bash
rosrun rm_65_demo pick_place_demo
节点运行后,在rviz中可以看到场景中添加了三个物体,分别代表两个桌子和一个抓取的目标物,然后机器人运动到目标物的位置将目标物附着到机器人上模拟抓取物体,接着进行运动规划将目标物体放置到另一个桌子上然后解除附着,最后机器人返回zero姿态,如图10-2所示:
 
图10-2 pick and place运行效果

11.指令驱动机器人编程示例---MoveJ指令

11.1概述

ROS节点api_moveJ_demo通过话题/rm_driver/MoveJ_Cmd将MoveJ指令发送给机械臂。机械臂接收MoveJ指令后通过内部集成算法完成路径规划并控制机械臂运动。本示例源码为C++代码,具体实现见代码注释。源代码位置:rm_65_demo/src/api_moveJ_demo.cpp。

11.2实现功能

自定义ROS节点api_moveJ_demo,该节点发布/rm_driver/MoveJ_Cmd为话题的rm_msgs::MoveJ类型消息(消息内容详见表7-2),该消息包含机械臂各个关节的角度信息以及运行速度信息。机器人驱动节点rm_driver通过订阅话题/rm_driver/MoveJ_Cmd,获取rm_msgs::MoveJ内的信息。rm_driver解析rm_msgs::MoveJ消息内容后,将该内容通过JSON协议封装并通过Socket发给机械臂。机械臂接收到MoveJ指令以及机械臂关节角度后,通过机械臂内部集成路径规划算法规划路径,并控制各关节转动相应角度。

11.3运行演示

首先打开终端,执行以下命令运行roscore:
rocore
然后打开一个新终端,执行以下命令运行机器人驱动节点rm_driver:
cd ~/ws_rmrobot/
source devel/setup.bash
rosrun rm_driver rm_driver
 节点rm_driver启动后,如图11-1所示。
 
图11-1 节点rm_driver启动成功界面
再打开一个新终端执行以下命令,运行api_moveJ_demo节点,控制机械臂各关节转动指定角度。
cd ~/ws_rmrobot/
source devel/setup.bash
rosrun rm_65_demo api_moveJ_demo
运行成功后,机械臂各个关节转动指定角度,由初始位姿运动到指定位姿。如图11-2与图11-3所示。
 

12.指令驱动机器人编程示例---MoveJ_P指令

12.1概述

ROS节点api_moveJ_demo通过话题/rm_driver/MoveJ_P_Cmd将MoveJ_P指令发送给机械臂。机械臂接收MoveJ_P指令后通过内部集成算法完成路径规划并控制机械臂运动。本示例源码为C++代码,具体实现见代码注释。源代码位置:rm_65_demo/src/api_moveJ_P_demo.cpp。

12.2实现功能

自定义ROS节点api_moveJ_P_demo,该节点发布/rm_driver/MoveJ_P_Cmd为话题的rm_msgs::MoveJ_P类型消息(消息内容详见表7-2),该消息包含机械臂末端的目标位姿以及运行速度信息。机器人驱动节点rm_driver通过订阅话题/rm_driver/MoveJ_P_Cmd,获取rm_msgs::MoveJ_P内的信息。rm_driver解析rm_msgs::MoveJ_P消息内容后,将该内容通过JSON协议封装并通过Socket发给机械臂。机械臂接收到MoveJ_P指令以及机械臂末端位姿后,通过机械臂内部集成路径规划算法规划路径,并控制机械臂末端到达指定位姿。该指令中的目标位姿必须是机械臂末端法兰中心基于基坐标系的位姿,用户在使用该指令前务必确保,否则目标位姿会出错!与MoveJ指令不同的是,MoveJ_P指令通过机械臂末端位姿控制机械臂运动。
12.3运行演示
首先打开终端,执行以下命令运行roscore:
rocore
然后打开一个新终端,执行以下命令运行机器人驱动节点rm_driver:
cd ~/ws_rmrobot/
source devel/setup.bash
rosrun rm_driver rm_driver
 节点rm_driver启动后,如图12-1所示。
 
图12-1 节点rm_driver启动成功界面
再打开一个新终端执行以下命令,运行api_moveJ_P_demo节点,控制机械臂末端到达指定位姿。
cd ~/ws_rmrobot/
source devel/setup.bash
rosrun rm_65_demo api_moveJ_P_demo
运行成功后,机械臂末端由初始位姿运动到指定位姿。如图12-2与图12-3所示。

13.指令驱动机器人编程示例---MoveL指令

13.1概述

ROS节点api_moveL_demo通过话题/rm_driver/MoveL_Cmd将MoveL指令发送给机械臂,机械臂接收MoveL指令后通过内部集成算法完成路径规划并控制机械臂末端由初始位姿沿直线运动到指定位姿。本示例源码为C++代码,具体实现见代码注释。源代码位置:rm_65_demo/src/api_moveL_demo.cpp。

13.2实现功能

自定义ROS节点api_moveL_demo,该节点发布/rm_driver/MoveL_Cmd为话题的rm_msgs::MoveL类型消息(消息内容详见表7-2),该消息包含机械臂末端的目标位姿以及运行速度信息。机器人驱动节点rm_driver通过订阅话题/rm_driver/MoveL_Cmd,获取rm_msgs::MoveL内的信息,rm_driver解析rm_msgs::MoveL消息内容后,将该内容通过JSON协议封装并通过Socket发给机械臂。机械臂接收到MoveL指令以及机械臂末端位姿后,通过机械臂内部集成路径规划算法规划路径,并控制机械臂末端沿直线到达指定位姿。

13.3运行演示

首先打开终端,执行以下命令运行roscore:
rocore
然后打开一个新终端,执行以下命令运行机器人驱动节点rm_driver:
cd ~/ws_rmrobot/
source devel/setup.bash
rosrun rm_driver rm_driver
 节点rm_driver启动后,如图13-1所示。
 
图13-1 节点rm_driver启动成功界面
再打开一个新终端执行以下命令,运行api_moveL_demo节点,控制机械臂末端沿直线到达指定位姿。为避免机械臂路径规划过程中出现不可达目标点,该过程中,首先通过MoveJ_P控制机械臂由初始位姿运动至过渡位姿(该位姿可保证机械臂执行MoveL时机械臂末端位姿可达),然后通过MoveL命令控制机械臂末端由过渡位姿沿直线运动至目标位姿。
cd ~/ws_rmrobot/
source devel/setup.bash
rosrun rm_65_demo api_moveL_demo
运行成功后,机械臂末端由初始位姿沿直线运动到指定位姿。如图13-2、图13-3与图13-4所示。
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

附件下载

0 条评论

关于作者

Forrest

让机械臂成为智能、易用、可靠、通用的作业工具,走入千行百业、千家万户。

选择发帖板块
选择发帖板块