Skip to content

单个电机

简介

由于实验室经常出现电机疑似寄了但实则没寄的、寄了很久但没被发现让开发者挠头等严重影响工作效率和工作热情的情况。为节省测试时间,特此编写该测试文档。可直接在GSRL库task.cpp中调用testMotor()函数进行测试。 此文档包含多人与电机苦战的血泪史。希望后续开发者不会被小小电机代码坑害。

checklist 多个电机均无法连接

  • 是否在不同的can上也存在相同id的3508(GSRL遗留问题)
  • can总线上是否有60欧姆终端电阻?(一般来说第一个和最远的一个开120欧电阻,其余不开)

checklist 单个电机

鉴于有时不一定需要单独拿下来看电机是否损坏,所以此checklist可帮助快速定位问题。 - 电机驱动器型号是否正确? - 电机是否有反馈?(查看电机反馈数据,Motor类下ismotorconnected) - can总线上是否有60欧姆(总)终端电阻? - 电机id是否正确? - PID是不是给的太小不足以驱动电机转动? - can线HL口是否接反? - can线、电源线通不通? -->打标 - 电调是否正确接上can口?电机是否正确接上电调? - 电调与电机是否匹配? - 电调是否有损坏? - 是否存在其他鬼线?

若以上均无问题,则电机大概率损坏。建议进入电机测试环节来证明猜测。

测试步骤

1. 打开GSRL库内tsk_test.cpp文件。找到电机型号4310的测试代码段(约29行)。

// Motor
MotorDM4310 motor(1, 0, 3.1415926f, 40, 15, &myPID);

Tip:请一定注意达妙4310,有两个id号参数,不要随意套用其他电机型号。

2. 修改电机型号和参数以匹配你的电机配置。(此处默认电机ID是1)

2325

MotorDM2325 motor(1,0,1, 1, 5, &myPID);

(该电机为力矩控制,P V 随意,T 最大给到5,具体数据参考电机设置,该数据可更改)

6020

MotorDM6020 motor(1,&myPID);

3508

MotorDM3508 motor(1,&myPID);

2006

MotorDM2006 motor(1,&myPID);

MG翎控

MotorLKMG mgMotor(1, &myPID);

J60

MotorJ60 motor(1,&myPID);

3. 根据需求修改mypid参数。约20行,原代码如下:

SimplePID::PIDParam param = {
    10.0f,  // Kp
    0.0f,   // Ki
    500.0f, // Kd
    10.0f,  // outputLimit
    0.0f,   // intergralLimit
};

注意: - PID参数需要根据电机型号和负载情况进行调整,建议参考电机手册或官方示例代码。(一定要改,p只给10一般来说驱动不了) - 注意P limit是否调大。

4. 角速度闭环控制输出。

while (1) {
        motor.angleClosedloopControl(1000.0f);
        transmitMotorsControlData();
        vTaskDelayUntil(&taskLastWakeTime, 1); // 确保任务以定周期1ms运行
    }

若测试MG翎控电机,请将闭环控制逻辑替换为MG类下的函数,即:

while (1) {
        mgMotor.speedClosedloopControl(1000.0f);
        transmitMotorsControlData();
        vTaskDelayUntil(&taskLastWakeTime, 1); // 确保任务以定周期1ms运行
    }

若测试J60电机,请加入motor.enable:

extern "C" void test_task(void *argument)
{
    CAN_Init(&hcan1, can1RxCallback);                  // 初始化CAN1
    UART_Init(&huart3, dr16ITCallback, 36);            // 初始化DR16串口
    motor.enable();                                    // 使能J60电机
    TickType_t taskLastWakeTime = xTaskGetTickCount(); // 获取任务开始时间
    while (1) {
        motor.angleClosedloopControl(1000.0f);
        transmitMotorsControlData();
        vTaskDelayUntil(&taskLastWakeTime, 1); // 确保任务以定周期1ms运行
    }
}