ros中使用zr_pwm16_pca9685

PCA9685模塊16路舵機控制板,作爲執行器控制板zr_pwm16_pca9685包可以用ros srv來控制擴展板上的舵機。
在這裏插入圖片描述

邏輯電壓3~5v
I2c通訊
使能
動力供電壓最大6V的說,試驗功率較的大舵機8V沒異常,(像sg90 9g這種不要冒險,電壓高了舵機可能會冒煙的)。

在這裏插入圖片描述
video
https://www.bilibili.com/video/BV1C7411C75B/

硬件節點

rospy.Service('zr_hw_cmd', hw_cmd, fun1)

ros節點

srv_name='zr_hw_cmd'
rospy.wait_for_service(srv_name)

srv 發送初始角位。ps(data) 返回ok
srv 使能。en() en(1||0)返回en狀態"0",“1”

/----------------------------------------------------------------------/

hw_cmd.srv
string cmd
uint8[] input
---
uint8[] output

cmd命令支持的字符串有:“n”,“v”,“b”,“c”,“ps”,“en”
n代表name
v代表version
b代表brand
c代表copyright

ps代表 position set 執行ps(input)
en代表 模塊使能 en()返回使能狀態 en(0||1)設置並返回使能狀態,使能後舵機纔會運動。
sm代表 慢速連續運動 平滑 sm(0||1)設置並返回平滑狀態

使用平滑sm(1),應先開啓en(1),再發送數據。
sm 開啓時段內只能控制某一個控制板所有端口的運動平滑。如果在運動結束之前,關閉了sm,會導致平滑失效,目標角位迅速到達。

脈衝的頻率、脈寬與input的數據格式的定義

//50hz 相當於20ms(20000us)的 週期, 4096分辨率,分辨率每單位佔用時間t 爲20000us/4096=4.8828125us
//舵機控制所需脈寬Th範圍0.5 ~ 2.5ms(500 ~ 2500us)因此高電平分辨率範圍就是Th/t =(102.4~512)個單位。

500/ 200004096=102.4
2500/ 20000
4096=512

500/4.8828125=102.4
2500/4.8828125=512
//取整 最小103 最大512 範圍是512-103=409;

#define SERVO_0 103
#define SERVO_45 205
#define SERVO_90 308
#define SERVO_135 410
#define SERVO_180 512

數據範圍是0~ 409,對應脈寬單位103~ 512,對應舵機角度0~ 180

數據使用一個字節
因爲“一個字節”範圍是0~255, 當使用低精度數據時,通訊時資源佔用會少,舵機角位精度減半,
一個字節不是0~ 255對應0~ 180;

由於舵機精度不一,爲了校準方便,
硬件程序根據數據來控制脈寬,可實現軟校準。
數據範圍之外有一個軟校準上下調整的範圍,硬件內定爲8;

精度減半,數據d值在硬件內再加上軟校準調整範圍8,再乘以2; (d+8)2=(103 ~ 512)
最值這樣求
dmin
2+16=103;dmin=44
dmax*2+16=512;dmax=248
這樣 44 ~ 248就 對應脈寬單位103 ~ 512,對應舵機角度0 ~ 180;

校準應根據實際情況,在44~248的基礎範圍上做適當縮放和偏移。
注意:軟校準調整範圍時不能跳躍過大,比如突然發送1或255,沒有保護措施這樣做有可能損壞舵機!損壞舵機! 損壞舵機!

數據使用兩個字節,數據範圍 0 ~ 65535,實際使用103 ~ 512,舵機精度提高 ,d=(103~512)

dmin=103;
dmax=512;

校準應根據實際情況,在103~512的基礎範圍上做適當縮放和偏移。
注意:軟校準調整範圍時不能跳躍過大,比如突然發送1或1024,沒有保護措施這樣做有可能損壞舵機!損壞舵機! 損壞舵機!

定義數據包
目標: 1控制單個端口, 2控制相鄰的一系列的端口,控制數據精度

硬件地址: 6bit AAAAAA(取值對應板上焊盤焊點)
端口號 : 4bit pppp
數據精度:2bit TT 每個數據的size 根據TT值確定分別爲8位低精度或16位高精度分辨率,即0 - 256或0-65535

字節數據包格式

|--------|--------|--------|--------|--------|--------|--------|...
|TTAAAAAA|----pppp|ddddddd0|ddddddd1|ddddddd2|ddddddd3|ddddddd4|...

TTAAAAAA----pppp佔兩個字節爲包頭,定義數據分辨率TT,定義了起始地址和端口,就可以找到對應控制板的幾號端口。

單字節數據
TT=0,AAAAAA=0,pppp=0

|00000000|----0000|ddvalue0|ddvalue1|ddvalue2|ddvalue3|ddvalue4|ddvalue5|...
0x00,0x00,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx...

雙字節數據
TT=1,AAAAAA=0,pppp=0

|01000000|----0000|dvalue0H|dvalue0L|dvalue1H|dvalue1L|dvalue2H|dvalue2L|dvalue3H|dvalue3L|dvalue4H|dvalue4L|dvalue5H|dvalue5L|...
0x40,0x00,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx...

單字節數據,硬件地址1,端口15
TT=0,AAAAAA=1,pppp=15

|00000000|----0000|ddvalue0|ddvalue1|ddvalue2|ddvalue3|ddvalue4|ddvalue5|...
0x01,0x0f,0xx1,0xx2,0xx3,0xx4,0xx5,0xx6...

注意:0xx1爲1號板15號端口的數據,多餘的數據,會發送到下一個硬件地址(+1)的對應端口(0-15),
1號板15號:0xx1
2號板00號:0xx2
2號板01號:0xx3
2號板02號:0xx4
2號板03號:0xx5
2號板04號:0xx6

依次類推。

因此上位機有比較靈活的控制方式。
還需注意:因爲單片機通訊緩存區大小爲固定值,所以ROS消息的大小不能超過300字節,
當發送單字節數據時每個ROS消息最多可以控制256個端口
當發送雙字節數據時每個ROS消息最多可以控制128個端口
當級聯板數量較多(>8或>16個)時,可以拆分兩個消息進行控制。
開啓 sm 後只能控制單個板所有端口的運動平滑,一次應發送16個端口的數據。不支持跨板和指定端口號的控制

示例代碼

roslaunch zr_pwm16_pca9685 pwm16_demo.launch
roslaunch zr_pwm16_pca9685 pwm16_fake.launch

video
https://www.bilibili.com/video/BV1C7411C75B/
gitbub
https://github.com/zaizhizhuang/zr

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章