2025年11月26日 星期三

DYNAMIXEL Protocol 2.0 (py uart demo)

 Python 透過 pyserial 函式庫向 /dev/ttyUSB0 埠發送您指定的 DYNAMIXEL Protocol 2.0 數據包的程式碼範例。

🚨 前置作業

您需要先安裝 pyserial 函式庫:

Bash
pip install pyserial

💻 Python 程式碼

這個程式碼會設定串列埠,並以二進位 (byte) 格式發送您提供的數據。

Python
import serial
import time
import binascii

# --- 串列埠設定 ---
SERIAL_PORT = '/dev/ttyUSB0'  # Linux 系統下通常是 ttyUSB0
BAUDRATE = 57600
TIMEOUT = 0.1  # 讀取逾時時間 (秒)

# --- 要發送的數據包 (Protocol 2.0 協定) ---
# FF FF FD 00 01 07 00 03 74 00 55 09 00 00 D5 27
# Header  ID Len(L/H) Instr Addr(L/H) Data(4 bytes) CRC(L/H)
# 數據包說明:
# ID: 01
# Instruction: 03 (WRITE)
# Address: 0x0074 (Goal Position)
# Data: 0x00000955 (2389, 這是 0x55 0x09 0x00 0x00 的 little-endian 轉換)
# CRC: 0xD5 0x27
HEX_STRING = "FFFFFD0001070003740055090000D527"

# 將十六進制字串轉換為 bytes
try:
    # binascii.unhexlify 將十六進制字串轉換為 bytes
    PACKET_TO_SEND = binascii.unhexlify(HEX_STRING)
except TypeError as e:
    print(f"錯誤:十六進制字串轉換失敗 - {e}")
    print("請檢查您的十六進制字串是否有效且長度為偶數。")
    exit(1)


def send_dynamixel_packet():
    """
    配置串列埠並發送 DYNAMIXEL 數據包。
    """
    print(f"嘗試開啟串列埠:{SERIAL_PORT},波特率:{BAUDRATE}")

    # 配置串列埠:57600 波特率,無奇偶校驗 (N),8 個數據位 (8),1 個停止位 (1)
    # pySerial 預設是 N, 8, 1
    try:
        ser = serial.Serial(
            port=SERIAL_PORT,
            baudrate=BAUDRATE,
            parity=serial.PARITY_NONE,
            stopbits=serial.STOPBITS_ONE,
            bytesize=serial.EIGHTBITS,
            timeout=TIMEOUT
        )
        
        # 確保連接是開啟的
        if not ser.isOpen():
            ser.open()

        print("串列埠開啟成功。")
        print(f"準備發送數據包 ({len(PACKET_TO_SEND)} bytes):")
        print(f"十六進制:{PACKET_TO_SEND.hex().upper()}")
        
        # --- 發送數據 ---
        bytes_written = ser.write(PACKET_TO_SEND)
        ser.flush() # 確保數據立即發送

        print(f"成功寫入 {bytes_written} 個位元組。")

        # --- 嘗試讀取回覆 (Status Packet) ---
        # 由於 DYNAMIXEL 會回覆一個狀態包 (Status Packet),我們嘗試讀取它。
        # Status Packet 的長度不固定,但通常約為 14-16 bytes 左右。
        print("\n等待 DYNAMIXEL 回覆 (Status Packet)...")
        time.sleep(0.01) # 短暫延遲,等待馬達處理和回覆
        
        response = ser.read(30) # 嘗試讀取最多 30 個位元組的回覆
        
        if response:
            print(f"收到回覆 ({len(response)} bytes):")
            print(f"十六進制:{response.hex().upper()}")
        else:
            print("未收到任何回覆 (逾時)。")
            
        # --- 關閉串列埠 ---
        ser.close()
        print("\n串列埠已關閉。")

    except serial.SerialException as e:
        print(f"\n錯誤:無法存取或配置串列埠 {SERIAL_PORT}。")
        print("請確認以下事項:")
        print(f"* 1. 串列轉接器已連接到 {SERIAL_PORT}。")
        print(f"* 2. 您有足夠的權限 (可能需要 'sudo' 或將使用者加入 'dialout' 群組)。")
        print(f"* 3. 埠號 ({SERIAL_PORT}) 是否正確。")
        print(f"詳細錯誤訊息: {e}")
    except Exception as e:
        print(f"發生一般錯誤: {e}")

# 執行函式
if __name__ == "__main__":
    send_dynamixel_packet()

📋 執行注意事項

  1. 使用者權限: 在 Linux 系統中,存取 /dev/ttyUSB0 通常需要特定的權限。如果遇到 Permission denied 錯誤,您可能需要使用 sudo 執行腳本,或者將您的使用者帳號添加到 dialout 群組:

    Bash
    sudo usermod -a -G dialout $USER
    # 之後需要登出並重新登入才能生效
    
  2. 埠號: 確保您的 USB-to-UART 轉接器或 U2D2 連接到電腦時確實被識別為 /dev/ttyUSB0。如果不是,請修改程式碼中的 SERIAL_PORT 變數。

  3. DYNAMIXEL 連接: DYNAMIXEL 馬達必須正確連接到 UART 轉接器上,且電源開啟,才能收到回覆。

UART/序列埠終端機工具

 Ubuntu (Linux) 系統擁有許多功能強大且類似於 Windows 下 SecureCRTPuTTY 

或您提到的 AccessPort 等工具的 UART/序列埠終端機應用程式。


這些工具通常用於調試硬體、與嵌入式設備(如 Arduino, Raspberry Pi, 或其他單片機)進行通信,或操作網路設備的 Console Port。


以下是 Ubuntu 中最常用且功能類似的 UART/序列埠終端機工具:

💻 終端機模擬器 (Terminal Emulators)

這些工具提供了圖形使用者介面 (GUI) 或命令列界面,用於建立、管理和監聽序列埠連接。

工具名稱類型特點
Minicom命令列 (CLI)這是 Linux/Unix 環境中最經典的序列埠工具之一。它類似於 DOS 時代的 Procomm 或 Windows 的超級終端機 (HyperTerminal)。功能強大,但需要透過鍵盤命令進行配置。
PuTTY圖形介面 (GUI)雖然 PuTTY 更常被用於 SSH 連接,但它也完全支援序列埠 (Serial Port) 連接,並提供 GUI 設定,使用體驗與 Windows 版本非常相似。
GTKTerm圖形介面 (GUI)一個簡單、輕量級的序列埠終端機。它提供了一個乾淨的 GUI,適合快速連接和基本測試。
CuteCom圖形介面 (GUI)專為序列埠通信設計,具有使用者友好的 GUI,支援發送十六進制數據和自定義行尾符號等功能。

🔍 命令列工具 (CLI Tools)

如果您只需要簡單地讀取或發送數據,並不需要複雜的會話管理,可以使用內建或輕量級的命令列工具:

  • screen

    • 主要是一個終端機多工工具,但它最常被用作最快速的序列埠監聽器。

    • 用法示例: screen /dev/ttyUSB0 115200

  • cu (Call Up):

    • 這是 uucp 套件的一部分,也是一個功能強大的序列埠連接工具。

  • cat

    • 在最簡單的情況下,您甚至可以使用 cat 命令來讀取序列埠數據(例如:cat /dev/ttyUSB0)。

🛠️ 安裝方式 (以 PuTTY 和 Minicom 為例)

您可以使用 apt 套件管理工具輕鬆安裝上述應用程式:

Bash
# 安裝 Minicom
sudo apt update
sudo apt install minicom

# 安裝 PuTTY (如果未預裝)
sudo apt install putty

# 安裝 GTKTerm
sudo apt install gtkterm

提示: 在 Linux 中,序列埠通常被命名為 /dev/ttyS0 (原生 COM port) 或 /dev/ttyUSB0, /dev/ttyACM0 (USB 轉序列埠轉接器)。在使用前,請確保您的使用者帳戶已加入 dialout 群組,以獲得序列埠的訪問權限。

DYNAMIXEL 協定 2.0 與 XL430-W250-T 整合要點

 

DYNAMIXEL 協定 2.0 與 XL430-W250-T 整合要點

您的機械手臂研究中若使用 XL430-W250-T 舵機,將主要透過 DYNAMIXEL Protocol 2.0 進行通訊和控制 3333

一、 XL430-W250-T 規格概覽

XL430-W250-T 是一款採用 ARM CORTEX-M3 (72 MHz, 32-bit) 的智能馬達 4,預設使用 DYNAMIXEL Protocol 2.0 5

規格項目詳細數據 (部分)備註 (與 ROS 整合相關)
輸入電壓

6.5V ~ 12.0V (建議 11.1V) 

需確保自走車電源供應穩定且符合範圍。
通訊方式

TTL 半雙工異步串行通信 

需使用適當的轉換器(如 OpenCR1.0, OpenRB-150, OpenCM9.04, U2D2 等)將 UART 訊號轉換為半雙工 8888888888888888

波特率

9,600 bps ~ 4.5 Mbps 

建議在設計階段確定一個高且穩定的波特率 (Baud Rate) 以確保 ROS 系統中的即時性。
控制模式

速度控制 (Velocity Control Mode)、位置控制 (Position Control Mode) 

Position Control Mode (預設) 11 最常用於機械手臂關節控制,對應 MoveIt 2 的規劃輸出。

位置解析度

$0.088^{\circ}/\text{pulse}$ 12121212

總解析度為 4,096 級(單圈)

扭力 (Stall Torque)

1.4 Nm (11.1V 時) 

影響手臂的負載能力,設計 URDF 模型時需考慮此限制。

二、 DYNAMIXEL Protocol 2.0 關鍵通訊包結構

DYNAMIXEL 協定 2.0 使用兩種結構化資料包:指令包 (Instruction Packet) (由控制器發送) 和 狀態包 (Status Packet) (由舵機返回) 15

1. 指令包結構 (Instruction Packet)

指令包用於向舵機提供命令 16

欄位 (Field)位元組大小描述
Header (標頭)

4 bytes 

(0xFF 0xFF 0xFD 0x00) 

指示封包開始

Packet ID (資料包 ID)1 byte

0-252 (特定舵機 ID);

254 (0xFE) 為廣播 ID

Length (長度 L/H)2 bytes

指令 (Inst)、參數 (Param) 和 CRC 欄位的總長度

Instruction (指令)1 byte

定義命令類型,如 READ (0x02) 或 WRITE (0x03)

Parameter (參數)N bytes

包含位址、資料長度或要寫入的數據

CRC2 bytes

16 位元校驗和,用於檢查封包完整性

2. 狀態包結構 (Status Packet)

狀態包是舵機在收到指令包後的回應 24

  • 結構與指令包相似,但新增了錯誤欄位 (Error Field) 25

  • Instruction (指令):固定為 0x55 (Status) 26

  • Error (錯誤):1 byte,指示指令處理結果,如 Result Fail (0x01)、CRC Error (0x03)、Access Error (0x07) 等 27272727272727272727272727272727

3. 關鍵指令與 ROS 應用對應

在 ROS 級別的控制中,以下指令特別重要:

指令 (Instruction)數值描述 (用途)適用於 ROS 應用
Ping

0x01 28

檢查設備是否存在並檢索基本資訊 29

初始化、設備發現 (Device Discovery)。
Read

0x02 30

從控製表讀取資料(如當前位置、速度) 31

獲取 joint_states,是 ROS 機器人狀態發布的數據來源。
Write

0x03 32

向控製表寫入單一數值(如目標位置、扭力啟用) 33

設置單個舵機的目標值或參數。
Reg Write

0x04 34

將指令註冊到待機狀態,用於後續的 Action 指令執行 35

用於同步控制:與 Action 配合,確保多個舵機同時啟動,減少時間差。
Action

0x05 36

執行所有已註冊的 Reg Write 指令 37

用於同步控制:確保機械手臂的多個關節同步移動。
Sync Read

0x82 38

一次從多個具有相同位址和長度的設備讀取數據 39

高效能數據採集:用於快速讀取所有關節的當前位置或速度。
Sync Write

0x83 40

一次向多個具有相同位址和長度的設備寫入資料 41

高效能控制:用於同時更新所有關節的目標位置 (Goal Position),但不支持返回狀態包 42

Bulk Read

0x92 43

一次從多個具有不同位址和不同長度的設備讀取數據 44

靈活數據採集:用於讀取不同關節的不同狀態(如 ID1 讀位置,ID2 讀電壓)。

三、 XL430-W250-T 控製表 (Control Table) 實用位址

控制機械手臂時,主要存取 RAM 區域的位址,因為這些數據是即時的,且在斷電後會重設 45

地址資料名稱大小 (bytes)屬性備註 (ROS 整合重點)
64Torque Enable (扭力啟用)

1 46

RW 47

1 為啟用扭力 (Torque ON),0 為關閉 (Torque OFF) 48484848。修改 EEPROM 需先設為 0 49

68Status Return Level (狀態返回等級)

1 50

RW 51

預設為 2 (返回所有指令的狀態包) 52525252。在高速通訊中,設為 1 (只返回 PING/READ) 或 0 (只返回 PING) 可減輕匯流排負載 53535353

104Goal Velocity (目標速度)

4 54

RW 55

用於速度控制模式 56。影響 Position Control Mode 下的 Profile 生成 57

108Profile Acceleration (設定加度)

4 58

RW 59

用於控制 MoveIt 2 產生的軌跡的加/減速曲線 60

112Profile Velocity (設定最大速度)

4 61

RW 62

用於 Position Control Mode,設定軌跡的最大速度 63

116Goal Position (目標位置)

4 64

RW 65

最重要! MoveIt 2 最終輸出並寫入的位置目標值 66

128Present Velocity (當前速度)

4 67

R 68

讀取舵機的即時輸出速度 69

132Present Position (當前位置)

4 70

R 71

讀取舵機的即時位置 72。這是 ROS joint_states 的主要數據。

144Present Input Voltage (當前輸入電壓)

2 73

R 74

監測電源狀態 75

146Present Temperature (當前溫度)

1 76

R 77

監測舵機是否過熱 78

專家指導總結

為了在 ROS 中高效且準確地控制 XL430-W250-T 機械手臂:

  1. 優先使用同步指令 (Sync Read / Sync Write) 79797979:由於機械手臂有多個關節,使用同步指令可以減少通訊時間,提高控制迴路的頻率 (Control Loop Frequency)。

  2. 精確的 URDF/XACRO 模型:必須使用正確的 XL430-W250-T 參數(如慣量矩、質量和幾何尺寸 80808080)來建立 URDF,這是 MoveIt 2 和動力學計算的基礎。

  3. Position PID 參數調校:請注意控制表中的 Position PID 增益(地址 80, 82, 84)81。在 MoveIt 2 規劃後,舵機本身的 PID 性能決定了追蹤軌跡的準確性。這將是一個關鍵的調校步驟。

您目前提供的資料,已足以開始進行底層的 DYNAMIXEL SDK 或 ros2_control 驅動程式的開發與整合工作。

下一步,您希望我針對 MoveIt 2 如何配置這些 DYNAMIXEL 參數(如 Goal Position 116, Profile Velocity 112)提供具體的 ROS 範例或指導嗎?