Skip to content

2.不考虑平滑的单点运动

我们控制器有三种模式:示教模式、运行模式、远程模式。

其中示教模式又存在:拖拽示教、点动示教。

本期将介绍如何在点动示教下进行单点的运动。

1、封装上电函数

单点运动是在点动示教下进行的,然而示教模式下的运动需要进行额外的一步上电操作,所以我们需要封装一个上电函数

cpp
/*
 * 封装上电函数
 */
void power_on(int fd)
{
    int state = 0;
    get_servo_state(fd, state);  // 查询当前伺服状态
    switch (state)
    {
    case 0: // 当前伺服处于停止
        set_servo_state(fd, 1);  // 将伺服设置为就绪
        set_servo_poweron(fd);   // 将伺服上电
        break;
    case 1: // 当前伺服处于就绪
        set_servo_poweron(fd);
        break;
    case 2: // 当前伺服处于报警
        clear_error(fd);         // 清除错误
        set_servo_state(fd, 1);
        set_servo_poweron(fd);
        break;
    }
    get_servo_state(fd, state);
    std::cout << "伺服状态: " << state << std::endl;
}

2、封装等待运动结束的函数

cpp
/*
 * 循环阻塞运动结束函数
 */
void wait_for_running_over(int fd)
{
    // 等待运动完成
    int running_state = 0;
    get_robot_running_state(fd, running_state);  // 查询机器人是否在运动 2-正在运动
    while (running_state == 2)
    {
        std::this_thread::sleep_for(std::chrono::milliseconds(500));  // 阻塞500ms
        get_robot_running_state(fd, running_state);   // 再次查询
    }
}

3、主要运动功能

将会用到延时函数,需要额外包含<thread>、<chrono>这两个头文件。

cpp
#include &lt;iostream>
#include &lt;thread>
#include &lt;chrono>
#include "cpp_interface/nrc_api.h"  // 导入头文件


int main()
{
    SOCKETFD fd = connect_robot("192.168.1.15", "6001");  // 连接控制器
    if (fd &lt;= 0)
    {
        std::cout << "连接失败" << std::endl;
        return 0;
    }
    std::cout << "连接成功: "<< fd << std::endl;

    set_current_mode(fd, 0);   // 设置示教模式,只有示教模式下的运动需要上电
    set_speed(fd, 50);         // 设置示教模式下的全局速度


    power_on(fd);              // 调用封装的上电函数


    // 查询运动前坐标
    std::vector&lt;double> pos(7);
    get_current_position(fd, 0, pos);
    std::cout << "关节运动前坐标:" << pos[0] << " " << pos[1] << " " << pos[2] << " " << pos[3] << " " << pos[4] << " " << pos[5] << " " << pos[6] << std::endl;


    // 构建运动指令,开始运动
    MoveCmd temp_cmd;
    temp_cmd.coord = 0;                                    // 设置关节坐标系
    temp_cmd.targetPosType = PosType::data;
    get_current_position(fd, 0, temp_cmd.targetPosValue);  // 获取当前的关节坐标
    temp_cmd.targetPosValue[0] += 10;                      // 基于当前位置 1轴向正方向移动10°
    temp_cmd.velocity = 50;                                // 指令速度,关节坐标系下速度范围[1,100]
    temp_cmd.acc = 100;                                    // 指令加速度
    temp_cmd.dec = 100;                                    // 指令减速度
    robot_movej(fd, temp_cmd);


    std::this_thread::sleep_for(std::chrono::milliseconds(200));  // 阻塞200ms
    wait_for_running_over(fd);   // 阻塞到运动结束


    // 查询运动后坐标
    get_current_position(fd, 0, pos);
    std::cout << "关节运动后坐标:" << pos[0] << " " << pos[1] << " " << pos[2] << " " << pos[3] << " " << pos[4] << " " << pos[5] << " " << pos[6] << std::endl;


    return 0;
}