HumansXドキュメントセンター 公式サイトへ ↗

実験2:四輪メカナムホイールカーの速度PID制御

実験の目的:

  1. モーターのPIDを応用し、複数のモーターの速度を同時に制御します。2. 四輪全方向メカナムホイールシャーシの基本的な運動制御(前進・後退・左平行移動・右平行移動)を習得します。

基本的な運動原理:

四輪全方向メカナムホイールシャーシは全方向への平行移動が可能で、そのためには各ホイールの回転方向を制御する必要があります。シャーシの移動方向と各ホイールの回転方向の関係は以下のとおりです。

前進 後退
右平行移動 左平行移動
その場で左旋回 その場で右旋回

ハードウェアの準備:

Arduino mega2560 メインボード * 1、uni mega2560 拡張ボード * 1、USBケーブル(Type-B)* 1、3S電池ボックス * 1、リチウム電池 * 3、エンコーダ付きモーター 30*4、エンコーダモーターケーブル(2.0→2.54)*4

試作構成:

実験7 サスペンション付き長方形フレームと四輪駆動全方向メカナムホイール駆動シャーシの構造設計​

回路接続

ハードウェアモジュール

ヒント:ハードウェアモジュールの使用説明

Uni Mega2560 拡張ボード ユーザーガイド[V1.1]

Arduino プログラミングソフトのインストールとライブラリのインポート [V2.1]

電池・電源モジュール使用上の注意(必読)[v3.0]

電子モジュールの紹介 [V3.0]

ピン配置

シャーシ mega2560 拡張ボード
車体の左前輪 M1
車体の右前輪 M2
車体の左後輪 M3
車体の右後輪 M4

各駆動輪の番号:

実機配線

ソフトウェアの実装:

ソースコードとライブラリのダウンロード

ソースコードリンク:(HumansX サポートより提供) AE /3.PID%E5%BC%80%E6%BA%90%E9%A1%B9%E7%9B% AE /2.%E5%9B%9B%E8%BD% AE %E9%BA%A6%E5%85%8B%E7%BA%B3%E5%A7%86%E8%BD% AE %E5%B0%8F%E8%BD%A6%E9%80%9F%E5%BA%A6PID%E6%8E%A7%E5%88%B6

ライブラリリンク:(HumansX サポートより提供)

ライブラリファイルのインポート:

インポートが必要なライブラリ:Unirobot_Mega_V1.2

プログラムコード:

mac_car_vel_test.ino がメインプログラムです。プロジェクトの完全なコードは(ソースコードリンク)からダウンロードしてください。

/***************************************************************************
编程环境:----------
    软件:Arduino2.3.4

实验目的:-----------
    本实验使用的编码电机速度范围为 (-1.0 ~ 1.0) 米/s
    -1.0 ~ 0: 电机反转,并且速度由最快到停止
    0 ~ 1.0 :电机正转,并且速度由停止到速度最快

实验现象:-----------
    实现小车前进,后退,左转,右转,左平移,右平移,停止。
    最终的实验效果,小车在地面上画矩形

实验接线简略图:----------
                                        车头
                                M1________________M2
                                  |                |
                                  |      Car       |
                                  |                |
                                  |________________|
                                M3                M4
                                        车尾
.__________________________________________________________________________________________
|  丝印标签    |对应程序标签|                     对应Mega2560引脚号                          \
|_____________|___________|_________________________________________________________________|
|     M1      |      1    |电机方向1:36  电机方向2:37  电机pwm:8   编码器A相:18  编码器B相:32  |
|     M2      |      2    |电机方向1:A2  电机方向2:A3  电机pwm:5   编码器A相:19  编码器B相:38  |
|     M3      |      3    |电机方向1:35  电机方向2:34  电机pwm:12  编码器A相:3   编码器B相:33  |
|     M4      |      4    |电机方向1:42  电机方向2:43  电机pwm:9   编码器A相:2   编码器B相:39  |
` ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄

库函数版本号:1.2
data:2025.8.18
****************************************************************************/

#include "uni_motor.h"

#define BORD_RATE 115200  //设定串口波特率为115200
UNI_MOTOR motor1(1);      //声明编码电机M1对象
UNI_MOTOR motor2(2);      //声明编码电机M2对象
UNI_MOTOR motor3(3);      //声明编码电机M3对象
UNI_MOTOR motor4(4);      //声明编码电机M4对象

float target_vel = -0.2;   //单位是米/秒

/*********************************************************
使用枚举类型定义小车工作状态
Forward:前进   Back:后退    Turnleft:左转    Turnright:右转
Transleft: 左平移    Transright:右平移    Stop:停止
*/
enum{Forward=1,Back,Turnleft,Turnright,Transleft,Transright,Stop};

void setup() {
  delay(500);
  Serial.begin(BORD_RATE);     //打开串口,并设置串口波特率
  Serial.println("begin");
  motor1.init();               //m1电机初始化
  motor2.init();               //m2电机初始化
  motor3.init();               //m3电机初始化
  motor4.init();               //m4电机初始化
  //小车运动测试
  motor_move(Transright, 2300);//小车右平移2300毫秒
  motor_move(Stop, 1200);      //小车停止1200毫秒

  motor_move(Forward, 2000);   //小车前进2000毫秒
  motor_move(Stop, 1200);      //小车停止1200毫秒

  motor_move(Transleft, 2200); //小车左平移2200毫秒
  motor_move(Stop, 1200);      //小车停止1200毫秒

  motor_move(Back, 2500);      //小车后退2500毫秒
  motor_move(Stop, 1200);      //小车停止1200毫秒
}

void loop() {

}

//更新四个编码电机状态函数
void motor_update(){
  motor1.update(); //更新编码电机1的位置
  motor2.update(); //更新编码电机2的位置
  motor3.update(); //更新编码电机3的位置
  motor4.update(); //更新编码电机4的位置
  delay(10);
}

/****************************************************************************
小车转动函数
motor_move(Forward, 2000);   //小车前进2000毫秒
motor_move(Back, 2500);      //小车后退2500毫秒
motor_move(Turnleft, 1800);  //小车左转1800毫秒
motor_move(Turnright,3200);  //小车右转3200毫秒
motor_move(Transleft, 2200); //小车左平移2200毫秒
motor_move(Transright, 2300);//小车右平移2300毫秒
motor_move(Stop, 1200);      //小车停止1200毫秒
*/
void motor_move(uint8_t car_mode, unsigned long action_delay){
  unsigned long time_now = millis();
  switch(car_mode){
    //小车前进,前进 action_delay 毫秒
    case Forward:
      while( (millis() - time_now) < action_delay ){
        motor1.set_vel(-target_vel);  motor2.set_vel(target_vel);
        motor3.set_vel(-target_vel);  motor4.set_vel(target_vel);
        motor_update();
      }break;
    //小车后退,后退 action_delay 毫秒
    case Back:
      while( (millis() - time_now) < action_delay ){
        motor1.set_vel(target_vel);  motor2.set_vel(-target_vel);
        motor3.set_vel(target_vel);  motor4.set_vel(-target_vel);
        motor_update();
      }break;
    //小车左转,左转 action_delay 毫秒
    case Turnleft:
      while( (millis() - time_now) < action_delay ){
        motor1.set_vel(target_vel);  motor2.set_vel(target_vel);
        motor3.set_vel(target_vel);  motor4.set_vel(target_vel);
        motor_update();
      }break;
    //小车右转,右转 action_delay 毫秒
    case Turnright:
      while( (millis() - time_now) < action_delay ){
        motor1.set_vel(-target_vel);  motor2.set_vel(-target_vel);
        motor3.set_vel(-target_vel);  motor4.set_vel(-target_vel);
        motor_update();
      }break;
    //小车左平移,左平移 action_delay 毫秒
    case Transleft:
      while( (millis() - time_now) < action_delay ){
        motor1.set_vel(target_vel);  motor2.set_vel(target_vel);
        motor3.set_vel(-target_vel);  motor4.set_vel(-target_vel);
        motor_update();
      }break;
    //小车右平移,右平移 action_delay 毫秒
    case Transright:
      while( (millis() - time_now) < action_delay ){
        motor1.set_vel(-target_vel);  motor2.set_vel(-target_vel);
        motor3.set_vel(target_vel);  motor4.set_vel(target_vel);
        motor_update();
      }break;
    //小车停止,停止 action_delay 毫秒
    case Stop:
      while( (millis() - time_now) < action_delay ){
        motor1.set_vel(0);  motor2.set_vel(0);
        motor3.set_vel(0);  motor4.set_vel(0);
        motor_update();
      }break;
    default: break;
  }
}

操作手順:

  1. メインプログラムを書き込みます。ボードの種類として Arduino mega または mega 2560 を選択し、ポート番号を選択してください。

  2. 電池ボックスのスイッチと拡張ボードのスイッチをオンにし、動作させて結果を確認します。

実験結果:

四輪メカナムホイールシャーシの基本的な運動制御(前進・後退・左平行移動・右平行移動)ができます。

サポート窓口

資料のダウンロード・技術サポートについては、HumansX株式会社までお問い合わせください。