![見出し画像](https://assets.st-note.com/production/uploads/images/144078480/rectangle_large_type_2_a0984f218ae1607298d088c14d74654b.png?width=1200)
Self Driving and ROS 2 - Learn by Doing! Odometry & Control: PID (セクション12-5/13)
Arduinoファームウェアを設定して、L298N Hブリッジとホイールエンコーダを用いたモーター制御を実装。
シミュレーションと実ロボットの両方のためのROS 2起動ファイルを作成し、Gazeboシミュレーションや実ハードウェアインターフェースを起動。
すべてをビルドし、ジョイスティックでロボットを制御して、シミュレーションおよび実環境でのテストを実施。
「Self Driving and ROS 2 - Learn by Doing! Odometry & Control」コースのセクション12「Build the Robot」の最後の部分では、ハードウェアとソフトウェアを統合してロボットを稼働させるための重要な手順について説明します。この包括的なガイドでは、レクチャー158から160までのハードウェア制御ファームウェアの設定、完全なロボットの起動、およびシミュレートおよび実世界のシナリオのためのROS 2起動ファイルの構成について詳しく説明します。
レクチャー158:Arduinoでロボットを制御する
Arduinoファームウェアの設定
最初のステップは、Arduinoを使用してロボットの制御を確立することです。`robot_control.ino`ファームウェアを記述し、L298N Hブリッジモータードライバおよびホイールエンコーダとインターフェースします。以下は主要なコンポーネントとプロセスの概要です:
ハードウェア接続:
L298N Hブリッジの接続ピン(PWMおよび方向制御)の定義。
ホイールエンコーダを設定して、ホイールの回転と方向を監視します。
PID制御:
各モーターの精密な速度制御を保証するためにPID制御を実装します。
右モーターと左モーターのPIDパラメータ(`Kp`、`Ki`、`Kd`)を初期化します。これらの値は、特定のモーターの特性に応じて微調整が必要になる場合があります。
シリアル通信:
ROS 2システムからの速度コマンドをシリアルポート経由で読み取り、解釈します。
右ホイールと左ホイールのコマンドとそれぞれの方向(前進または後退)を区別するプロトコルを実装します。
速度計算:
エンコーダの読み取りを使用して、ホイールの速度をラジアン毎秒で計算します。
PIDコントローラの出力に基づいてモーターコマンドを更新し、望ましい速度を維持します。
コンパイルとアップロード:
ファームウェアをコンパイルし、Arduino Nanoにアップロードします。
サンプルファームウェアコード
#include <PID_v1.h>
// L298N Hブリッジ接続ピン
#define L298N_enA 9 // PWM
#define L298N_enB 11 // PWM
#define L298N_in4 8 // Dir Motor B
#define L298N_in3 7 // Dir Motor B
#define L298N_in2 13 // Dir Motor A
#define L298N_in1 12 // Dir Motor A
// ホイールエンコーダ接続ピン
#define right_encoder_phaseA 3 // Interrupt
#define right_encoder_phaseB 5
#define left_encoder_phaseA 2 // Interrupt
#define left_encoder_phaseB 4
// ... (追加のセットアップおよびループコード)
void setup() {
// ハードウェアとPIDコントローラの初期化
pinMode(L298N_enA, OUTPUT);
pinMode(L298N_enB, OUTPUT);
pinMode(L298N_in1, OUTPUT);
pinMode(L298N_in2, OUTPUT);
pinMode(L298N_in3, OUTPUT);
pinMode(L298N_in4, OUTPUT);
rightMotor.SetMode(AUTOMATIC);
leftMotor.SetMode(AUTOMATIC);
Serial.begin(115200);
// エンコーダの初期化
pinMode(right_encoder_phaseB, INPUT);
pinMode(left_encoder_phaseB, INPUT);
attachInterrupt(digitalPinToInterrupt(right_encoder_phaseA), rightEncoderCallback, RISING);
attachInterrupt(digitalPinToInterrupt(left_encoder_phaseA), leftEncoderCallback, RISING);
}
void loop() {
// シリアルポートからホイール速度コマンドを読み取り、解釈します
// PIDコントローラを使用して新しいモーターコマンドを計算します
// エンコーダの読み取り値をROS 2システムに送信します
}
レクチャー159:完全なロボットを起動する
ROS 2起動ファイル
開発と展開のフェーズ間をシームレスに移行するために、シミュレートおよび実際のロボット環境のための起動ファイルを作成します。
シミュレート環境:
Gazeboシミュレーション、コントローラノード、およびジョイスティックテレオペレーションを起動するための`simulated_robot.launch.py`起動ファイルを作成します。
import os
from launch import LaunchDescription
from launch.actions import IncludeLaunchDescription
from ament_index_python.packages import get_package_share_directory
def generate_launch_description():
gazebo = IncludeLaunchDescription(
os.path.join(
get_package_share_directory("bumperbot_description"),
"launch",
"gazebo.launch.py"
),
)
controller = IncludeLaunchDescription(
os.path.join(
get_package_share_directory("bumperbot_controller"),
"launch",
"controller.launch.py"
),
launch_arguments={
"use_simple_controller": "False",
"use_python": "False"
}.items(),
)
joystick = IncludeLaunchDescription(
os.path.join(
get_package_share_directory("bumperbot_controller"),
"launch",
"joystick_teleop.launch.py"
),
)
return LaunchDescription([
gazebo,
controller,
joystick,
])
実ロボット環境:
実際のロボットのためのハードウェアインターフェース、コントローラノード、およびジョイスティックテレオペレーションを起動するための`real_robot.launch.py`起動ファイルを作成します。
import os
from launch import LaunchDescription
from launch.actions import IncludeLaunchDescription
from ament_index_python.packages import get_package_share_directory
def generate_launch_description():
hardware_interface = IncludeLaunchDescription(
os.path.join(
get_package_share_directory("bumperbot_firmware"),
"launch",
"hardware_interface.launch.py"
),
)
controller = IncludeLaunchDescription(
os.path.join(
get_package_share_directory("bumperbot_controller"),
"launch",
"controller.launch.py"
),
launch_arguments={
"use_simple_controller": "False",
"use_python": "False"
}.items(),
)
joystick = IncludeLaunchDescription(
os.path.join(
get_package_share_directory("bumperbot_controller"),
"launch",
"joystick_teleop.launch.py"
),
)
return LaunchDescription([
hardware_interface,
controller,
joystick,
])
レクチャー160:すべてをまとめる
すべての準備が整ったら、ROS 2ワークスペースをビルドし、起動ファイルを実行して、シミュレーション環境および実ロボット環境でロボットをテストします。
ワークスペースのビルド:
cd ~/bumperbot_ws
colcon build
実ロボットの起動:
. install/setup.bash
ros2 launch bumperbot_bringup real_robot.launch.py
ジョイスティックを使用したテスト:
ジョイスティックがUSBまたはBluetoothで接続されていることを確認します。
ジョイスティックを使用してロボットを制御し、リアルタイムでその応答を観察します。
結論
「Self Driving and ROS 2 - Learn by Doing! Odometry & Control」コースのセクション12の最後の部分を完了することは、自動運転ロボットの構築の旅における重要なマイルストーンです。Arduinoファームウェアの統合、ROS 2起動ファイルの構成、およびシミュレートおよび実環境でのロボットのテストを通じて、理論的な知識と実践的な応用を橋渡しする貴重な実践経験を
得ることができます。ロボットの構築と運転を楽しんでください!