我们执行命令,运行aubo机械臂(以仿真环境为例):
roslaunch aubo_i10_moveit_config moveit_planning_execution.launch
roslaunch aubo_demo MoveGroupInterface_To_Kinetic.launch
执行命令 rosnode list ,发现系统中活跃的节点有:
/MoveGroupInterface_To_Kinetic
/aubo_driver
/aubo_joint_trajectory_action
/aubo_robot_simulator
/move_group
/robot_state_publisher
/rosout
/rviz_jupj_virtual_machine_24743_2290800773247990345
这些节点中跟我们密切相关的是/MoveGroupInterface_To_Kinetic 、/aubo_driver 、/aubo_joint_trajectory_action 。
一、/MoveGroupInterface_To_Kinetic
aubo_robot/aubo_demo/src/MoveGroupInterface_To_Kinetic.cpp中创建了该节点。该节点调用MoveIt! API接口,进行路径规并将规划到的信息通过move_group节点发布出去。该节点根据用户的需要实现相应的功能。也就是说,在实际项目中,这就是你创建的节点(当然根据项目复杂程度的不同,可以有多个类似节点)。
我们打开这个cpp文件,可以看到aubo官方在这个文件中,使用代码设置aubo机械臂在世界坐标系中的位置和姿态。我们在实际项目中,可以参考aubo官方提供的例程,实现我们需要的功能(控制机械臂到达真实世界中的指定位置和呈现指定姿态,这个指定的位置和姿态一般需要外界来提供,如3D相机)。
二、/aubo_driver
该节点往下连接真实的机械臂控制器,设置机械臂的运动参数,发送MoveIt!为机械臂计算出来的路径(每个joint的关节角值) ,获取机械臂的状态,并将这些参数向上发送给move_group(MoveIt!)、rouout、aubo_robot_simulator、robot_state_punlisher、rviz等需要获取该消息的节点。aubo_driver节点是离机械臂控制器最近的节点,直接与机械臂控制器进行命令和数据的交互。
我们打开aubo_driver/src/driver_node.cpp文件,该文件里面只有一个main函数:
using namespace aubo_driver;
int main(int argc, char **argv)
{
ros::init(argc, argv, "aubo_driver");//注册aubo_driver节点
ros::NodeHandle n;
/*从参数服务器获取机械臂关节轴的数量*/
int num = 0;
ros::param::get("/aubo_driver/external_axis_number", num);
int N = 3;
while(num == 0 && N < 0)
{
sleep(1);
ros::param::get("/aubo_driver/external_axis_number", num);
N--;
}
/*以关节轴的数量为参数,实例化robot_driver*/
AuboDriver robot_driver(num);
robot_driver.run();
/*使用6个线程来处理该节点的业务*/
ros::A