✅ 讓 PWM 訊號來自真實馬達控制板(Arduino / STM32)
要讓 PWM 來自 Arduino 或 STM32,我們需要:
- 讓 ROS 2 與 Arduino / STM32 通訊(使用
ros2_serial
或ros2_socketcan
)。 - 讓 Arduino / STM32 接收
cmd_vel
並轉換為 PWM 訊號。 - 用
ros2_control
讓cmd_vel
控制馬達。 - 測試並調整 PWM 轉速輸出。
📌 1️⃣ 讓 ROS 2 與 Arduino / STM32 通訊
選擇通訊方式
方法 | 硬體需求 | 適用情境 |
---|---|---|
USB (Serial) | Arduino / STM32 | 最簡單 |
CAN Bus (ros2_socketcan ) | STM32(有 CAN 模組) | 工業級應用 |
WiFi (ros2_microros / MQTT) | ESP32 / STM32 | 無線通訊 |
這裡我們用 Serial (USB) 作示範,適用於 Arduino 和 STM32。
✅ 設定 ROS 2 與 Arduino 通訊
安裝 ros2_serial
sudo apt install ros-${ROS_DISTRO}-rosserial-arduino ros-${ROS_DISTRO}-rosserial
在 Arduino 上安裝 ROS 2
- 下載 Arduino ROS 庫
cd ~/Arduino/libraries git clone https://github.com/ros-drivers/rosserial.git
- 在 Arduino IDE 中開啟
rosserial
範例- 選擇
ros_lib
庫,開啟HelloWorld
,確保 Arduino 能與 ROS 通訊。
- 選擇
📌 2️⃣ Arduino / STM32 轉換 cmd_vel
為 PWM
📜 Arduino 代碼
#include <ros.h>
#include <geometry_msgs/Twist.h>
// 定義 PWM 輸出腳位
#define LEFT_MOTOR_PWM 5
#define RIGHT_MOTOR_PWM 6
ros::NodeHandle nh;
// 設定最大 PWM 值
const int MAX_PWM = 255;
void cmdVelCallback(const geometry_msgs::Twist& msg) {
float linear = msg.linear.x; // 直線速度
float angular = msg.angular.z; // 旋轉速度
// 轉換成 PWM 值
int left_pwm = constrain((linear - angular) * MAX_PWM, -MAX_PWM, MAX_PWM);
int right_pwm = constrain((linear + angular) * MAX_PWM, -MAX_PWM, MAX_PWM);
// 設定 PWM 輸出
analogWrite(LEFT_MOTOR_PWM, abs(left_pwm));
analogWrite(RIGHT_MOTOR_PWM, abs(right_pwm));
// 設定方向 (簡單 H 橋控制)
digitalWrite(4, left_pwm > 0);
digitalWrite(7, right_pwm > 0);
}
ros::Subscriber<geometry_msgs::Twist> sub("cmd_vel", cmdVelCallback);
void setup() {
nh.initNode();
nh.subscribe(sub);
pinMode(LEFT_MOTOR_PWM, OUTPUT);
pinMode(RIGHT_MOTOR_PWM, OUTPUT);
pinMode(4, OUTPUT); // 左馬達方向
pinMode(7, OUTPUT); // 右馬達方向
}
void loop() {
nh.spinOnce();
delay(10);
}
📌 3️⃣ 設定 ros2_control
📜 ros2_control.yaml
設定
controller_manager:
ros__parameters:
update_rate: 100
joint_state_broadcaster:
type: joint_state_broadcaster/JointStateBroadcaster
diff_drive_controller:
type: diff_drive_controller/DiffDriveController
diff_drive_controller:
ros__parameters:
left_wheel_names: ["left_wheel_hinge"]
right_wheel_names: ["right_wheel_hinge"]
publish_rate: 50
base_frame_id: "chassis"
wheel_separation: 0.3
wheel_radius: 0.1
use_stamped_vel: false
open_loop: false
velocity_command_interface: "velocity"
linear:
x:
has_velocity_limits: true
max_velocity: 1.0
has_acceleration_limits: true
max_acceleration: 1.5
angular:
z:
has_velocity_limits: true
max_velocity: 2.0
has_acceleration_limits: true
max_acceleration: 2.5
這讓 Gazebo 的
cmd_vel
直接發送給 Arduino / STM32。
📌 4️⃣ 啟動 ROS 2 並測試
✅ 啟動 Arduino Serial 通訊
ros2 run rosserial_python serial_node.py /dev/ttyUSB0 _baud:=57600
/dev/ttyUSB0
是 Arduino / STM32 的 USB 端口。
✅ 啟動 Gazebo
ros2 launch gazebo_ros gazebo.launch.py
✅ 啟動 ros2_control
ros2 control load_controller --set-state start joint_state_broadcaster ros2 control load_controller --set-state start diff_drive_controller
✅ 測試 cmd_vel
ros2 topic pub /cmd_vel geometry_msgs/msg/Twist "{linear: {x: 0.5}, angular: {z: 0.0}}"
- 這會讓 Arduino 讀取速度,並轉換成 PWM 訊號。
🚀 你還需要什麼?
- 要把
PWM
訊號轉成RPM
反饋回 ROS 2? - 要讓
STM32
透過CAN Bus
接收cmd_vel
? - 要測試
PID 控制
,讓 PWM 更穩定?
沒有留言:
張貼留言