在 Ubuntu 22.04 虚拟机中调试宇树 A1 电机

226 阅读7分钟

在 Ubuntu 22.04 虚拟机中调试宇树 A1 电机

  • 相关文献

Ubuntu22.04虚拟机平台环境搭建教程见链接
juejin.cn/post/756722…

宇树科技 文档中心

阶段 1:硬件连接与虚拟机设置

1.1 硬件连接

  • 电源:确保 A1 电机已连接到 24V 直流电源。

  • 通信:使用一个 USB-to-RS485 适配器。

  • 接线:将 USB-to-RS485 适配器的 AB 端连接到 A1 电机的 RS485 AB 端口。

  • 隔离:确保在这条 RS485 总线上只连接了这一个电机

d1176126f8e9f897d5d37e28a9131433.jpg 1.2 虚拟机环境准备

  1. 启动 Ubuntu 22.04 虚拟机。

  2. 在虚拟机菜单(通常是顶部或底部的 “虚拟机” -> “可移动设备” 或 USB 图标)中,找到你的 USB-to-RS485 适配器(例如 "FTDI" 或 "CH340"),并选择 “连接到此虚拟机”。 50edc128648730be38119ed84d6ca3af.png

  3. 打开 Ubuntu 终端,安装编译所需的依赖:

    sudo apt update
    sudo apt install build-essential cmake
    

1.3 查找串口设备

  1. 在 Ubuntu 终端中,运行以下命令来查找你的适配器被分配到的设备名:

    ls /dev/ttyUSB*
    
  2. 你应该会看到输出,例如:

/dev/ttyUSB0

请记住这个名称,这就是你的串口路径。

故障排除:如果提示 没有那个文件或目录,说明你的 USB 适配器没有被虚拟机正确“直通”。请返回步骤 1.2,拔插 USB 设备,并确保在虚拟机菜单中选中了它。)


阶段 2:编译官方 SDK 工具

  1. 将你拥有的 unitree_actuator_sdk 文件夹(在本次调试中为 unitree_actuator_sdk-A1B1) 放置到你的主目录(例如 ~/Downloads)下。

  2. 进入该目录,并创建 build 文件夹来编译项目:

    # cd 到 SDK 根目录
    cd ~/Downloads/unitree_actuator_sdk
    
    # 创建并进入 build 文件夹
    mkdir build
    cd build
    
    # 运行 cmake
    cmake ..
    
    # 编译
    make
    
  3. 编译完成后,你会在 build 文件夹内看到 changeIDexample_a1_motor 两个可执行文件。


阶段 3:使用 changeID 设置电机 ID

此步骤将电机的 ID 设置为一个已知值(例如 2),以便后续程序可以调用它。

  1. 确保你仍在 build 目录中。

  2. 使用 sudo 权限运行 changeID 程序:

    sudo ./changeID
    
  3. 程序会提示输入串口名称: Please input the name of serial port.(e.g. Linux:/dev/ttyUSB0, Windows:\\.\COM3)

  4. 输入你在步骤 1.3 中找到的名称,然后按 Enter 键:

    /dev/ttyUSB0
    

5. 程序会尝试发送广播命令。你可能会看到警告,这是正常的: [WARNING] SerialPort::recv, unblock version, wait time out [WARNING] motor id=187 does not reply
(解释:id=187 是 0xBB 的十进制,即广播ID。电机收到广播命令时不需要回复,所以此警告可忽略。)

  1. 程序会显示提示,表示已进入“ID修改模式”:
    Please turn the motor. One time: id=0; Two times: id=1, Three times: id=2 ID can only be 0, 1, 2 Once finished, press 'a `

image.png

  1. 执行操作

    • 用手转动A1电机的输出轴。你会感觉到它在“咔-咔”地跳动(电子拨轮模式)。

    • 根据提示,为了将 ID 设置为 2,你需要转动电机直到感觉到 3 次“咔”的跳动

    • 完成后,停止转动。

  2. 保存ID

    • 在终端中,按下 a 键,然后按 Enter 键。

    • 程序会发送“保存ID”的命令并退出。

    • 至此,你的电机 ID 已被设置为 2


阶段 4:使用 example_a1_motor 测试电机

此步骤用于验证 ID 是否设置成功,并测试电机的实际转动和数据反馈。

  1. 修改示例代码以匹配 ID

    • example_a1_motor 默认控制的 ID 可能不是 2。我们需要修改它。

    • 回到 SDK 根目录,编辑 example_a1_motor.cpp 文件:

      cd ~/Downloads/unitree_actuator_sdk
      gedit example/example_a1_motor.cpp
      
    • 在文件中找到设置 ID 的行(例如 cmd.id = 0;cmd.id = 1;),将其修改为你刚刚设置的 ID 2

      cmd.id = 2;
      
    • 保存文件并退出 (按 Ctrl+O, Enter, Ctrl+X)。

  2. 重新编译

    • 回到 build 目录并重新运行 make

      cd build
      make
      
  3. 运行测试

    • 确保电机已固定好,防止转动时跳动。

    • 运行修改后的程序:

      sudo ./example_a1_motor
      

阶段 5:测试位置控制 (伺服模式)

这是 STM32 项目的核心目标:控制电机转到特定圈数(位置)。我们将修改 example_a1_motor.cpp 来实现“转动1圈并保持”。

  1. 重要概念:转子端 vs 输出端

    • 宇树A1电机使用手册.pdf宇树A1电机数据手册.pdf 明确指出,A1 电机的减速比约为 9.1 (或 9)。

    • 所有的控制指令(Pos, W, K_P, K_W)都是发送给减速器前的电机转子的,而不是最终的输出轴 4。

    • 因此,要让输出轴转 1 圈 (6.28 弧度),你需要命令电机转子6.28 * 9.1 弧度 5。

  2. 修改示例代码 (位置模式)

    • 打开 example_a1_motor.cpp 文件:

      cd ~/Downloads/unitree_actuator_sdk
      gedit example/example_a1_motor.cpp
      
    • 将其 while(true) 循环中的命令部分修改为如下内容。我们使用 mode = 10 (FOC伺服模式) 6666,并设置 kpkd

      #include <unistd.h>
      #include "serialPort/SerialPort.h"
      #include "unitreeMotor/unitreeMotor.h"
      #define circle -2	//A1电机目标圈数
      
      int main() {
      
        SerialPort  serial("/dev/ttyUSB0");
        MotorCmd    cmd;
        MotorData   data;
      
        while(true) 
        {
              cmd.motorType = MotorType::A1;
              data.motorType = MotorType::A1;
              cmd.mode  = queryMotorMode(MotorType::A1,MotorMode::FOC); // 模式10:闭环伺服
              cmd.id    = 0;          // 你设置好的 ID
              cmd.kp    = 0.007;       // 位置刚度 Kp (一个示例值)
              cmd.kd    = 0.7;        // 速度刚度 Kd (一个示例值)
      
              // 目标:输出轴转 1 圈 (6.28 弧度)
              // 减速比为 9.1 (来自手册)
              cmd.q     = 6.28 * 9.1*circle; // 目标位置 (转子端)
              cmd.dq    = 0.0;        // 目标速度 0
              cmd.tau   = 0.0;        // 前馈力矩 0
      
              serial.sendRecv(&cmd,&data);
      
          std::cout <<  std::endl;
          std::cout <<  "motor.q: "    << data.q    <<  std::endl;
          std::cout <<  "motor.temp: "   << data.temp   <<  std::endl;
          std::cout <<  "motor.W: "      << data.dq      <<  std::endl;
          std::cout <<  "motor.merror: " << data.merror <<  std::endl;
          std::cout <<  std::endl;
      
          usleep(200);
        }
      
      }
      

    保存文件并退出 (按 Ctrl+O, Enter, Ctrl+X)。

  3. 重新编译

    cd build
    make
    
  4. 运行测试 (位置模式)

    • 安全警告:确保电机已固定。此命令会使电机立即转动circle圈(2圈)强力锁止

    • cmd.kp & cmd.kd调参
      cmd.kp从很小的值(0.001开始),如果刚开始扭矩太大导致电机响应太快,则减小cmd.kp,如果电机转速太慢,则增大cmd.kp
      cmd.kd大致为cmd.kp的10倍,如果最后到达目标圈数的时候存在震荡,则增大cmd.kd

    • 运行程序:

      sudo ./example_a1_motor
      
    • 预期结果

      • 电机快速转动 circle圈(circle*360度)。

      • 电机强力地保持在 circle圈的位置,你用手无法转动它。

      • 终端会打印 merror: 0,并且 motor.q 的值会稳定在 -111.496 附近 (即 6.28 * 9.1*circle)。

        image.png


阶段 6:测试阻尼模式(待完善)

阻尼模式让电机变得“粘稠”,它会抵抗运动,但不会锁定位置。这在机器人腿部落地时非常有用。

  1. 修改示例代码 (阻尼模式)

    • 根据手册,阻尼模式是速度模式的一种特例,设置 W=0 7。

    • 终端输入 gedit example/example_a1_motor.cpp 打开文件,并修改 while(true) 循环:

      // ... (while(true) 循环内部)
      cmd.mode  = queryMotorMode(MotorType::A1,MotorMode::FOC); // 模式10
      cmd.id    = 2;
      cmd.kp    = 0.0;        // Kp 设为 0
      cmd.kd    = 3.0;        // 仅设置 Kd (阻尼)
      cmd.q     = 0.0;        // 目标位置 0
      cmd.dq    = 0.0;        // 目标速度 0
      cmd.tau   = 0.0;
      // ...
      
  2. 重新编译并运行

    cd build
    make
    sudo ./example_a1_motor
    
  3. 预期结果

    • 电机不会主动转动。

    • 用手转动电机输出轴:你会感觉到一股与你转动速度成正比的阻力,就像在转动一个粘稠的旋钮。

    • 松手:电机会停在当前位置,而不是返回原点。


阶段 7:测试力矩模式(待完善)

此模式让电机输出恒定的力矩,这对于模拟弹簧或施加恒定压力很有用。

  1. 修改示例代码 (力矩模式)

    • 根据手册,力矩模式需要将 KpKd 都设为 0 8。

    • 终端 gedit example/example_a1_motor.cpp 打开文件,并修改 while(true) 循环:

      // ... (while(true) 循环内部)
      cmd.mode  = queryMotorMode(MotorType::A1,MotorMode::FOC); // 模式10
      cmd.id    = 2;
      cmd.kp    = 0.0;        // Kp 设为 0
      cmd.kd    = 0.0;        // Kd 设为 0
      cmd.q     = 0.0;
      cmd.dq    = 0.0;
      cmd.tau   = 0.5;        // 设置一个较小的前馈力矩 (单位 N.m)
      // ...
      
  2. 重新编译并运行

    cd build
    make
    sudo ./example_a1_motor
    
  3. 预期结果

    • 电机开始以一个恒定的(较小的)力矩转动。

    • 注意:由于没有负载,电机会持续加速直到达到最大速度 9。

    • 你可以用手感觉到它在"使劲",但你可以轻易地阻止它。