小白学稚晖君dummy机械臂代码(一)

        在稚晖君readme中,提到Ctrl-Step驱动的使用方式,通过CAN或者串口发送指令即可控制电机。关于指令的说明见源代码`UserApp`文件夹的`interface_can.cpp`和`interface_uart.cpp`。接下来,就让我们一起来学习interface_can.cpp里的内容吧!

        该代码是一个CAN总线通信的回调函数,在接收到CAN消息时被调用。根据收到的命令,执行相应的操作,操作大概分三部分控制设定操作的命令带有内存操作的命令以及一些一些查询命令,首先,让我们来学习第一部分的内容。

首先定义了一个CAN_TxHeaderTypeDef类型的变量txHeader,用于发送CAN消息。CAN_TxHeaderTypeDef是一个结构体类型,用于配置CAN消息的发送参数

#include "common_inc.h"
#include "configurations.h"
#include <can.h>


extern Motor motor;
extern EncoderCalibrator encoderCalibrator;

CAN_TxHeaderTypeDef txHeader =  //定义了一个CAN_TxHeaderTypeDef类型的变量txHeader,(CAN_TxHeaderTypeDef是一个结构体类型,用于配置CAN消息的发送参数)
    {
        .StdId = 0x00, //id
        .ExtId = 0x00,  //扩展id
        .IDE = CAN_ID_STD,//标准帧结构
        .RTR = CAN_RTR_DATA,//数据帧
        .DLC = 8,          //数据长度
        .TransmitGlobalTime = DISABLE
    };

在OnCanCmd函数中,根据收到的命令_cmd,执行不同的操作。

0x01: 启用电机

0x02: 执行编码器校准

    switch (_cmd)
    {
        // 0x00~0x0F No Memory CMDs
        case 0x01:  // Enable Motor 启动电机
            motor.controller->requestMode = (*(uint32_t*) (RxData) == 1) ?   //如果收到数据为“1”,则设置为第一个模式,否则设置为第二个模式
                                            Motor::MODE_COMMAND_VELOCITY : Motor::MODE_STOP;
            break;
        case 0x02:  // Do Calibration(执行编码器校准)
            encoderCalibrator.isTriggered = true;//将encoderCalibrator.isTriggered设置为true,表示触发编码器的校准过程。
            break;

接下来是一些电流、速度、位置的设定。

只要看懂一个以后,你会发现这些参数的设定都大同小异,以设置位置设定值为例。

  1. 判断modeRunning是否为位置控制模式
  2. 不是的话先设定为该模式
  3. 设置位置设定值
  4. 经过处理后调用函数将消息发出去。
        case 0x05:  // Set Position SetPoint  //设置位置设定值
            if (motor.controller->modeRunning != Motor::MODE_COMMAND_POSITION)
            {
                motor.config.motionParams.ratedVelocity = boardConfig.velocityLimit;
                motor.controller->SetCtrlMode(Motor::MODE_COMMAND_POSITION);
            }
            motor.controller->SetPositionSetPoint(
                (int32_t) (*(float*) RxData * (float) motor.MOTOR_ONE_CIRCLE_SUBDIVIDE_STEPS));
            if (_data[4]) // Need Position & Finished ACK 判断_data[4]的值,_data[4]的值为非零(即为真),表示需要发送位置和完成状态的确认消息
            {
                tmpF = motor.controller->GetPosition(); //调用GetPosition函数获取当前位置
                auto* b = (unsigned char*) &tmpF;//转换为unsigned char数组,存储在_data中
                for (int i = 0; i < 4; i++)
                    _data[i] = *(b + i);
                _data[4] = motor.controller->state == Motor::STATE_FINISH ? 1 : 0; //_data[4]设置为1或0,表示是否完成状态。
                txHeader.StdId = (boardConfig.canNodeId << 7) | 0x23;
                CAN_Send(&txHeader, _data);//调用CAN_Send函数将确认消息发送出去
            }
            break;

接下来看剩下的,还有不懂的也可以看看代码中的注释哦

        case 0x03:  // Set Current SetPoint  设置电流设定值
            if (motor.controller->modeRunning != Motor::MODE_COMMAND_CURRENT) //如果motor.controller不是电流控制模式
                motor.controller->SetCtrlMode(Motor::MODE_COMMAND_CURRENT);//用SetCtrlMode函数设置为电流控制模式
            motor.controller->SetCurrentSetPoint((int32_t) (*(float*) RxData * 1000)); /*通过motor.controller->SetVelocitySetPoint函数
                                                                                        设置速度设定值。*/
            break;
        case 0x04:  // Set Velocity SetPoint设置速度设定值
            if (motor.controller->modeRunning != Motor::MODE_COMMAND_VELOCITY)
            {
                motor.config.motionParams.ratedVelocity = boardConfig.velocityLimit;//将电机的额定速度设置为boardConfig.velocityLimit
                motor.controller->SetCtrlMode(Motor::MODE_COMMAND_VELOCITY);
            }
            motor.controller->SetVelocitySetPoint(   /*调用motor.controller->SetVelocitySetPoint函数
                                                     将计算得到的速度设定值设置给电机控制器*/
                (int32_t) (*(float*) RxData *  //解析RxData中的数据,将其转换为float类型
                           (float) motor.MOTOR_ONE_CIRCLE_SUBDIVIDE_STEPS)); /*乘以motor.MOTOR_ONE_CIRCLE_SUBDIVIDE_STEPS转换为int类型,
                                                                           得到速度设定值*/
            break;
        case 0x05:  // Set Position SetPoint  //设置位置设定值
            if (motor.controller->modeRunning != Motor::MODE_COMMAND_POSITION)
            {
                motor.config.motionParams.ratedVelocity = boardConfig.velocityLimit;
                motor.controller->SetCtrlMode(Motor::MODE_COMMAND_POSITION);
            }
            motor.controller->SetPositionSetPoint(
                (int32_t) (*(float*) RxData * (float) motor.MOTOR_ONE_CIRCLE_SUBDIVIDE_STEPS));
            if (_data[4]) // Need Position & Finished ACK 判断_data[4]的值,_data[4]的值为非零(即为真),
                        //表示需要发送位置和完成状态的确认消息
            {
                tmpF = motor.controller->GetPosition(); //调用GetPosition函数获取当前位置
                auto* b = (unsigned char*) &tmpF;//转换为unsigned char数组,存储在_data中
                for (int i = 0; i < 4; i++)
                    _data[i] = *(b + i);
                _data[4] = motor.controller->state == Motor::STATE_FINISH ? 1 : 0; //_data[4]设置为1或0,表示是否完成状态。
                txHeader.StdId = (boardConfig.canNodeId << 7) | 0x23;
                CAN_Send(&txHeader, _data);//调用CAN_Send函数将确认消息发送出去
            }
            break;
        case 0x06:  // Set Position with Time设置带有时间的位置设定值
            if (motor.controller->modeRunning != Motor::MODE_COMMAND_POSITION)
                motor.controller->SetCtrlMode(Motor::MODE_COMMAND_POSITION);
            motor.controller->SetPositionSetPointWithTime(
                (int32_t) (*(float*) RxData * (float) motor.MOTOR_ONE_CIRCLE_SUBDIVIDE_STEPS),
                *(float*) (RxData + 4));
            if (_data[4]) // Need Position & Finished ACK
            {
                tmpF = motor.controller->GetPosition();
                auto* b = (unsigned char*) &tmpF;
                for (int i = 0; i < 4; i++)
                    _data[i] = *(b + i);
                _data[4] = motor.controller->state == Motor::STATE_FINISH ? 1 : 0;
                txHeader.StdId = (boardConfig.canNodeId << 7) | 0x23;
                CAN_Send(&txHeader, _data);
            }
            break;
        case 0x07:  // Set Position with Velocity-Limit//设置带有速度限制的位置设定值
        {
            if (motor.controller->modeRunning != Motor::MODE_COMMAND_POSITION)
            {
                motor.config.motionParams.ratedVelocity = boardConfig.velocityLimit;
                motor.controller->SetCtrlMode(Motor::MODE_COMMAND_POSITION);
            }
            motor.config.motionParams.ratedVelocity =
                (int32_t) (*(float*) (RxData + 4) * (float) motor.MOTOR_ONE_CIRCLE_SUBDIVIDE_STEPS);
            motor.controller->SetPositionSetPoint(
                (int32_t) (*(float*) RxData * (float) motor.MOTOR_ONE_CIRCLE_SUBDIVIDE_STEPS));
            // Always Need Position & Finished ACK
            tmpF = motor.controller->GetPosition();
            auto* b = (unsigned char*) &tmpF;
            for (int i = 0; i < 4; i++)
                _data[i] = *(b + i);
            _data[4] = motor.controller->state == Motor::STATE_FINISH ? 1 : 0;
            txHeader.StdId = (boardConfig.canNodeId << 7) | 0x23;
            CAN_Send(&txHeader, _data);
        }
            break;

是不是再看其他的就感觉轻松多啦!

  • 13
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值