天天看點

執行個體4:樹莓派GPIO控制舵機轉動執行個體4:樹莓派GPIO控制舵機轉動

執行個體4:樹莓派GPIO控制舵機轉動

實驗目的

  1. 通過背景知識學習,了解舵機的外觀及基本運動方式。
  2. 了解四足機器人mini pupper腿部單個舵機的組成結構。
  3. 通過GPIO對舵機進行轉動控制,熟悉PWM。
  4. 了解mini pupper舵機組的整體調零。

實驗要求

使用Python語言程式設計,在程式設計中使用PWM方法,通過樹莓派GPIO控制外部舵機來回擺動,角度範圍為0°~180°,周期為四秒。

實驗知識

1. 什麼是舵機?

舵機(servomotor)是一種簡化版本的伺服電機,是位置伺服的驅動器,能夠通過輸入PWM信号控制旋轉角度,具備輕量、小型、簡化和成本效益高的特點。

舵機适用于那些需要角度不斷變化并可以保持的簡單控制系統,它能實作較為精确的電機控制,在航模、遙控玩具、機器狗等品類上運用良好。

執行個體4:樹莓派GPIO控制舵機轉動執行個體4:樹莓派GPIO控制舵機轉動

圖檔1:一般舵機的外觀

2. 舵機的運動方式

舵機的運動方式是繞軸擺動,“舵機”一詞也和它的運動方式有關,舵機常用來擺動調整方向,就像海洋上的水手的舵一樣,航模和船模常常用舵機的擺動來調整一些零部件的角度。

圖檔2:舵機的運動動圖

3. 舵機的組成結構

舵機一般是由保護外殼、内部內建控制晶片、小型直流電機、減速器齒輪組、位置檢測單元構成的。

當主要給舵機發出轉動信号時,控制晶片驅動電機開始轉動,通過減速器将動力傳達到輸出軸上的擺臂,由位置檢測單元回報轉動結果信号給主要進行回報調節。

一般來說,位置檢測單元可以是可變電阻,當舵機轉動時,可變電阻随之改變,由此可得轉動的角度資訊。舵機包含了電機、傳感器和控制器,是一個內建度高的、完整的伺服電機系統。

執行個體4:樹莓派GPIO控制舵機轉動執行個體4:樹莓派GPIO控制舵機轉動

圖檔3:舵機的内部結構拍攝

4. mini pupper定制舵機的部分硬體參數

芒砀科技MANGDANG針對mini pupper的運動需求,在原型舵機的基礎上優化改進了機械結構,定制了mini pupper專用舵機,這使得mini pupper的控制更加精确、動力更加澎湃。

執行個體4:樹莓派GPIO控制舵機轉動執行個體4:樹莓派GPIO控制舵機轉動

圖檔3:定制舵機的外觀

參考連結:mini pupper定制電機規格書 課程附件 MiniPupper-Servo-Spec.pdf

5.mini pupper舵機的控制方法

對于舵機的控制,首先要了解其基本硬體參數以及舵機對信号通訊的要求。

如圖所示,mini pupper一代舵機允許PWM的直接使用,也就是說,舵機可以直接連接配接到樹莓派上的GPIO_PWM端口使用而不需要考慮通訊協定,這對機器人入門開發者來說較為友好。

執行個體4:樹莓派GPIO控制舵機轉動執行個體4:樹莓派GPIO控制舵機轉動

圖檔4:舵機端口的連線

mini pupper一代舵機部分參數表

name value
端口1(黃) PWM Signal
端口2(紅) Vcc
端口3 (棕) GND
信号周期 20ms
信号頻率 50HZ
脈沖長度範圍 500us-2500us to 0°~180°
脈沖長度對應占空比 2.5% - 12.5%
信号高電平範圍 2V-5V
信号低電平範圍 0.0V-0.45V
中間位對應脈沖 1500 μsec

需要注意的是:

占空比=脈寬/周期

脈寬500us-2500us對應的占空比為2.5% - 12.5%

6. RPi的GPIO庫中PWM的用法

GPIO.setmode(GPIO.BOARD) #初始化GPIO引腳編碼方式,需放在代碼正式開始處
GPIO.setup(12, GPIO.OUT) #初始化GPIO引腳設定,需放在代碼正式開始處
           

參考連結:RPi GPIO庫中PWM()函數的詳細資料

實驗步驟

1. 編寫Python程式 servo_PWM_GPIO.py

#!/usr/bin/python
# coding:utf-8
# servo_PWM_GPIO.py
# 樹莓派GPIO控制外部舵機來回擺動,角度範圍為0~180°,周期為4秒。
try:
    import RPi.GPIO as GPIO
except RuntimeError:
    print("Error importing RPi.GPIO!  This is probably because you need superuser privileges. "
          " You can achieve this by using 'sudo' to run your script")
import time


def servo_map(before_value, before_range_min, before_range_max, after_range_min, after_range_max):
    """
    功能:将某個範圍的值映射為另一個範圍的值
    參數:原範圍某值,原範圍最小值,原範圍最大值,變換後範圍最小值,變換後範圍最大值
    傳回:變換後範圍對應某值
    """
    percent = (before_value - before_range_min) / (before_range_max - before_range_min)
    after_value = after_range_min + percent * (after_range_max - after_range_min)
    return after_value


GPIO.setmode(GPIO.BOARD)  # 初始化GPIO引腳編碼方式
servo_SIG = 32
servo_VCC = 4
servo_GND = 6
servo_frec = 50
servo_time = 0.01
servo_width_min = 2.5
servo_width_max = 12.5
# servo_degree_div =servo_width_max - servo_width_min)/180
GPIO.setup(servo_SIG, GPIO.OUT)
# 如果你需要忽視引腳複用警告,請調用GPIO.setwarnings(False)
# GPIO.setwarnings(False)
servo = GPIO.PWM(servo_SIG, servo_frec)  # 信号引腳=servo_SIG 頻率=servo_frec in HZ
servo.start(0)
servo.ChangeDutyCycle(servo_width_min)  # 回歸-90°
print('預設定完成,兩秒後開始擺動')
time.sleep(2)
try:  # try和except為固定搭配,用于捕捉執行過程中,使用者是否按下ctrl+C終止程式
    while 1:
        for dc in range(1, 181, 1):
            dc_trans = servo_map(dc, 0, 180, servo_width_min, servo_width_max)
            servo.ChangeDutyCycle(dc_trans)
            # print(dc_trans)
            time.sleep(servo_time)
        time.sleep(0.2)
        for dc in range(180, -1, -1):
            dc_trans = servo_map(dc, 0, 180, servo_width_min, servo_width_max)
            servo.ChangeDutyCycle(dc_trans)
            # print(dc_trans)
            time.sleep(servo_time)
        time.sleep(0.2)
except KeyboardInterrupt:
    pass
servo.stop()  # 停止pwm
GPIO.cleanup()  # 清理GPIO引腳
           

2. 運作程式servo_PWM_GPIO.py并觀察效果

在servo_PWM_GPIO.py的目錄下執行以下指令:

sudo python servo_PWM_GPIO.py
           

此時應觀察到舵機在樹莓派的控制下來回擺動,角度範圍為0°~180°,周期為四秒。

3. 嘗試運作Python程式 servo_PWM_GPIO_2.py[可選]

如果你希望嘗試手動輸入一個角度值來轉動舵機,你可以試試servo_PWM_GPIO_2.py

#!/usr/bin/python
# coding:utf-8
# servo_PWM_GPIO_2.py
# 輸入一個角度值,舵機将轉動到對應的角度
try:
    import RPi.GPIO as GPIO
except RuntimeError:
    print("Error importing RPi.GPIO!  This is probably because you need superuser privileges. "
          " You can achieve this by using 'sudo' to run your script")
import time


def servo_map(before_value, before_range_min, before_range_max, after_range_min, after_range_max):
    """
    功能:将某個範圍的值映射為另一個範圍的值
    參數:原範圍某值,原範圍最小值,原範圍最大值,變換後範圍最小值,變換後範圍最大值
    傳回:變換後範圍對應某值
    """
    percent = (before_value - before_range_min) / (before_range_max - before_range_min)
    after_value = after_range_min + percent * (after_range_max - after_range_min)
    return after_value


GPIO.setmode(GPIO.BOARD)  # 初始化GPIO引腳編碼方式
servo_SIG = 32
servo_VCC = 4
servo_GND = 6
servo_frec = 50
servo_time = 0.01
servo_width_min = 2.5
servo_width_max = 12.5
# servo_degree_div =servo_width_max - servo_width_min)/180
GPIO.setup(servo_SIG, GPIO.OUT)
# 如果你需要忽視引腳複用警告,請調用GPIO.setwarnings(False)
# GPIO.setwarnings(False)
servo = GPIO.PWM(servo_SIG, servo_frec)  # 信号引腳=servo_SIG 頻率=servo_frec in HZ
servo.start(0)
servo.ChangeDutyCycle(servo_width_min)  # 回歸-90°
print('預設定完成,兩秒後開始等待輸入')
time.sleep(2)
# 為舵機指定位置
try:    # try和except為固定搭配,用于捕捉執行過程中,使用者是否按下ctrl+C終止程式
    while 1:
        position = input("請輸入0°-180°的角度值:\n")
        if position.isdigit()==1:
            dc = int(position)
            if (dc>=0) and (dc<=180):
                dc_trans=servo_map(dc, 0, 180,servo_width_min,servo_width_max)
                servo.ChangeDutyCycle(dc_trans)
                print("已轉動到%d°處"%dc)
            else:
                print("Error Input:Exceed Range")
        else:
            print("Error Input:Not Int Input")
except KeyboardInterrupt:
    pass

servo.stop()  # 停止pwm
GPIO.cleanup()  # 清理GPIO引腳
           

4.嘗試調零[可選]

為了確定控制精度,mini pupper上的舵機組通常在使用前先進行一次調零。

試試在指令行中運作舵機調零腳本 run_set_neatral.sh

sudo ./run_set_neatral.sh
           
#!/usr/bin/env sh

# step 1 stop robot service
systemctl stop robot

# step 2 set neatral position

echo 1500000 > /sys/class/pwm/pwmchip0/pwm0/duty_cycle
echo "pwm 0 setting pwm off parameter --> 90 degree "

echo 1500000 > /sys/class/pwm/pwmchip0/pwm1/duty_cycle
echo "pwm 1 setting pwm off parameter --> 90 degree"

echo 500000 > /sys/class/pwm/pwmchip0/pwm2/duty_cycle
echo "pwm 2 setting pwm off parameter --> 0 degree"

echo 2500000 > /sys/class/pwm/pwmchip0/pwm3/duty_cycle
echo "pwm 3 setting pwm off parameter --> 180 degree"

sleep 1

echo "Done ! "
           

如果希望了解校準的詳細資訊,你可以檢視mini pupper的官方文檔:校準

確定 Mini Pupper 已預先組裝好,使用GUI校準工具來優化腿部的位置。

對于每條腿,移動杆,使所有腿都成 45 度角。 腿的角度會随着滑動條在螢幕上的位置而變化。

如果它不動,則說明您執行的步驟不正确。

您可以使用 iPhone 的傾斜傳感器app、尺子或量角器來測量角度。

實驗總結

經過本知識點的學習和實驗操作,你應該能達到以下水準:

知識點 内容 了解 熟悉 掌握
舵機 舵機的外觀及基本運動方式
舵機 單個舵機的組成結構
PWM PWM方法對舵機進行轉動控制
調零與校準 mini pupper舵機組的調零與校準

版權資訊:教材尚未完善,此處預留版權資訊處理方式

mini pupper相關内容可通路:https://github.com/mangdangroboticsclub

繼續閱讀