基於MATLAB步態算法仿真的六足仿生機器人


一、概述

1.研究意義

  隨着人類對在復雜環境中既具備高移動能力,又具備可靠性,且易於擴展的移動平台日益迫切的需求,步行機器人作為一種擁有全方位移動能力的移動運載平台,具有非常廣闊的應用前景。從仿生學角度來講,多足機器人分為仿人、仿四足哺乳動物、仿昆蟲行走機器人。在眾多步行機器人中,模仿昆蟲以及其他節肢動物的肢體結構和運動控制策略而創造出的六足機器人具有代表性。

  一般來說,仿人機器人重點研究人機交互、語音識別、圖像識別技術,行走重點為動態平衡;仿四足機器人多為中小型機器人,兼顧負重能力與靈活性,行走方面既有靜態步行穩定性也有動態運動研究;仿昆蟲機器人從尺寸上分為重載大型六足機器人和小型六足機器人,重點研究仿生腿的優化設計、行走穩定、足端精確控制、足端腳力分配、步態規划等。

  六足機器人較二足、四足機器人,具有控制結構相對簡單、行走平穩、肢體榮譽等特點,故而擁有較好的機動性,最容易實現穩定行走,可適應於復雜地形,多用於軍事勘察、礦山開采、核能工業、星球探測、消防及營救、建築業等領域。

 2.昆蟲的運動原理。

  足是昆蟲的運動器官。

  昆蟲有3對足,在前胸、中胸和后胸各有一對,相應地稱為前足、中足和后足。

  每個足由基節、轉節腿節脛節跗節前跗節幾部分組成。基節是足最基部的一節,多粗短。轉節常與腿節緊密相連而不活動。腿節是最長最粗的一節。第四節叫脛節,一般比較細長,長着成排的刺。第五節叫跗節,一般由2-5個亞節組成﹔為的是便於行走。在最末節的端部還長着兩個又硬又尖的爪,可以用它們來抓住物體。 行走是以三條腿為一組進行的,即一側的前、后足與另一側的中足為一組。這樣就形成了一個三角形支架結構,當這三條腿放在地面並向后蹬時,另外三條腿即抬起向前准備替換。 前足用爪固定物體后拉動蟲體向前,中足用來支持並舉起所屬一側的身體,后足則推動蟲體前進,同時使蟲體轉向。 這種行走方式使昆蟲可以隨時隨地停息下來,因為重心總是落在三角支架之內。並不是所有成蟲都用六條腿來行走,有些昆蟲由於前足發生了特化,有了其他功用或退化,行走就主要靠中、后足來完成了。 

圖1  昆蟲運動原理腿部示意圖

3.腿部機構類型

  一般來說,腿的構造形式可分為昆蟲類和哺乳動物類兩種不同形式。昆蟲類生物其腿的數目較多, 一般在四足以上 ;其腿分布於身體的兩側, 身體重心低,穩定性好,且運動靈活,但過低的重心不利於昆蟲的越障能力 ;喃乳動物的行走腿則通常為兩足或四足,且腿多分布於身體下方,重心高,便於快速奔跑和越障,但在轉向等需要靈活性的場合不如昆蟲類有優勢。

  通常腿部結構可以分為轉動關節和平動關節。轉動關節即通過電機轉動,帶動腿部直接旋轉,關節轉角即為電機轉角;平動關節即通過執行缸伸縮,從而帶動腿部旋轉,關節轉角需要通過平動距離進行轉化。

 

4.六足機器人步態

  通俗地說,步態是行走系統抬腿和放腿的順序。

(1)相關定義

  a.步態:是指機器人的每條腿按一定的順序和軌跡的運動過程,正是因為這一運動過程實現了機器人的步行運動

  b.步態周期::步態周期是指多足機器人完成一個步態所需的時間,也就是所有腿輪番完成一次“提起 -擺動-放下”的動作共花費的時間,在此過程中機器人機體也完成過渡過程

  c.占地系數:占地系數是指每條腿接觸地面的時間和整個步態周期的比值。

   當占地系數等於 0.5時,機器人是用兩組腿交替擺動,這種步態稱為小跑步態;

   當占地系數小於 0.5時,機器人任何瞬間只有不足三條腿支撐地面,稱為跳躍步態,

   當占地系數大於 0.5時,機器人輪番有三條腿以上支撐地面,這種步態俗稱慢爬行步態

  d.步幅:機器人的重心在一個步態周期中的平移為步幅。本系統中步幅為6cm。系統步幅參數也是可調的。
  e.靜態穩定性:步態的生成策略則取決於機器人的步行穩定性,即在步態生成時必須進行穩定性分析。對於多足機器人,在任何時候都要有足夠多的腿立足於地面支撐機器人機體,才能確保它靜態穩定地步行。通常,至少需要三條這樣的腿,並且由這三條腿的立足點構成的三角形必須包圍機器人的重心垂直投影,機器人步行時,雖然這個三角形區域是不停變化的,但只要機器人重心投影始終在這個交替變化的區域內,則機器人的步行就是穩定的.

(2)常見的步態

  a.三角步態
  三角步態也稱交替三角步態,是“六足綱”昆蟲最常使用的一種步態,也被譽為最快速有效的靜態穩定步態。大部分六足機器人都是從仿生學的角度出發使用這一步態。昆蟲三角步態的移動模式較簡單,非常適合步行架構的機器人的直線行走,行進速度也比較快。
  b.跟導步態
  對於六足機器人來說,跟導步態的重點是選擇前兩足下一步的落點,而一對中足和一對后足的下一步落點由當前前足和中足的立足點決定。跟導步態每次只需要選擇前兩足的立足點,因而具有控制簡單,穩定性較好,越溝能力強等特點,所以特別適合多足步行機在不平地面行走時采用。

  c.交替步態
  單腿交替行走步態,也被稱為五角步態。在交替步態中,各腿的運動可分為抬升和前進兩個部分。當某腿的相鄰各腿均已觸地時,該腿開始運動,並給其相鄰各腿發出信號。同樣,在該腿觸地時,也會給相鄰各腿發出觸地信號。這樣,一旦整個六足系統進入行走狀態,這種順次的步態運行狀態就可以一直維持下去。由於各腿等待其相鄰腿觸地的時間取決於其相鄰腿的動作及其觸地位置,因而,對於崎嶇不平的地面而言,這種步態本身是不可預測的。然而,對於理想的平整地面而言,各腿的運動周期應該是一致的,故而此時的交替步態實質上等同於三角步態。

二、設計內容及實現目標

  1.步態模擬:利用生物步態模擬“螃蟹步”和“節肢昆蟲”兩種步態

  2.動作設計:前進、后退、左轉、右轉等動作

  3.無線視頻及實時傳輸、GPS模塊定位

  4.紅外避障、循跡

  5.平台搭載功能模塊,如機械臂實現夾取物等功能。

三、機械結構設計

  設計內容:根據仿生學原理,建立機體和腿部結構,對機身底板的外形及腿部安放角度、單腿節段長度比例進行設計計算 ,並設計確定機器人足端形狀和結構;對運動過程中的極限狀態進行負載計算,校核舵機的額定轉矩是否能夠滿足工況;

  六足機器人行走方式與輪式、履帶式車輛行進方式有明顯區別,其行走軌跡為非連續的離散點,而輪式和履帶式車輛行走軌跡為連續接觸面。六足機器人落足點的離散性為六足機器人在不規則地形行走提供了卓越的越障能力,每個落足點之間的跨越方式和運動軌跡的變化都為六足機器人提供了不同的步態,不同的步態決定了不同的受力形式,同樣制約着機械結構的設計原則。反之,不同的機械結構也決定了機器人整機應對不同工況的能力。作為六足機器人的執行機構單腿剛度對整機性能影響較大,單腿受力后足端位移變形決定着機器人足端能否完成預定的軌跡。 下面為詳細設計。

1. 機器人底板布局設計

   對於擺動腿的仿昆蟲式六足機器人,六條腿的布置方位對機身穩定性和運動性能有很大影響,通常有三種布局:矩形、橢圓形和圓形布局。建立圖示三種布局,當每條腿擺動相同角度,即腿部掃過的扇形面積一致的情況下:

  (1)腿部在行進時的干涉情況:矩形布局的腿部擺動范圍重合度最高,圓形布局的重合度最小,即在保證相鄰腿部不干涉的情況下,圓形布局腿部擺動空間最大,橢圓布局次之,矩形布局最差;

  (2)直線行走的有效行進距離:設定單腿邁步可以完成的最大邁步距離為λ,標出每種布局的邁步距離,可見圓型布局的邁步距離最小,橢圓較大,矩形最大。

  綜合考慮上述因素,橢圓形布局的靈活性最佳,擬用橢圓布局,且自然界中六足昆蟲腿部分布也均為橢圓形。

圖2 三種底板布局示意圖

  六足機器人的穩定性由重心投影位置和支撐平面關系來確定,即相對固定的機器人重心位置不僅要保證時刻在變化的支撐平面內,更要預留出一定量的安全距離d。建立橢圓形機架連桿模型俯視圖,其中 L 為單腿俯視投影長度,a 為機架前端和末端寬度,b 為機架中間寬度的一半,c 為機架長度的一半。

圖3 穩定性分析示意圖

  穩定裕度為:d=(b+L)siny

  其中,中間變量:

    y=arctan(c/((2b-a)/2)+2L+a)

  根據計算結果可見,當設定c值和 L為固定長度時,a 值越小,b 值越大可使整機在一定范圍內穩定裕度 d 越高,當 a 充分小,b 充分大時整機重心將與支撐三角形最左側邊距離最近,但此種比例極不協調,通常設計時不做考慮。可見實際上圓形布局下的穩定裕度最大,考慮到機器人直線行走性能優選橢圓形布局作為本文的整機布局方案。

 底板最終設計的三維模型如下:

 

圖4  三維模型和二維尺寸圖

2. 機器人腿部結構設計

   主流腿部結構有兩種,一種是哺乳動物單腿結構,即直立腿結構,運動形式類似於在豎直平面內做鍾擺運動;一種是仿昆蟲單腿結構,即擺動腿結構,如圖所示。

圖5  兩種腿部結構

  在本設計中,考慮到大腿承受較大彎矩,且大腿寬度受限,因而將大腿上下腹板設計為板材形式,大腿側向和小腿均采用連桿形式,關節處連接舵機;另外在腿板上開設減重孔,且大腿和小腿均采用矩形截面,抗彎能力強,結構加工性好,且承載力強,方便搭載功能模塊。小腿采用變截面設計,無多余負重,質量小,有效減少了腿部結構末端的慣量,控制更容易,節約了驅動能量。

   整體來說,腿部結構方案主要由基節連桿、大腿連桿、小腿連桿組成,大腿連桿根部與基節連桿連接舵機旋轉端,大腿連桿末端與小腿連桿同樣的方式連接,足端設計為
弧形結構,足端底部安裝有較厚的橡膠墊,用於足端落地緩沖。

  關於尺寸:基節連桿的存在實際上是使足端運動范圍遠離機器人本體,雖然足端運動扇形區域更廣,但距離機體太遠的足端扇形觸地面會導致前后腿的接觸地面干涉大,因而基節連桿加長並無明顯優勢。在實際布置中,基節連桿越短越有利於提高機器人的通過性,縮小寬度。因而基節的長度僅能滿足舵機的安裝即可。大腿與小腿的長度尺寸暫定比例為1:1.5,外形根據仿生學按照昆蟲腿型進行設計。

  三維結構如圖所示。

 

圖6 三維結構圖

3.機器人足端結構

  在足端設計方面,足式機器人足端結構可分為兩類:一類是有足端被動關節的機構。另一類是固定式足端,即足端無被動關節而僅有緩沖材料組成的固定形狀的足端。無被動關節的足端在觸地和運動時有極小的慣量,能量消耗低,活動更為靈活。但足端在觸地過程中隨着機體結構的移動,小腿相對於地面的夾角發生變化,因而在運動控制上如果僅僅控制足端上的某一點的軌跡會導致足端與地面打滑,在大型足式機器人結構中這種打滑會產生極大的作用力。此種無被動關節的足端多應用在小型足式機器人上,且機器人多可跑步前進或以小碎步前進,通過這種行進方式可避免固定式足端的弊端。

  相比之下,有被動關節的足端在支撐移動的過程中,小腿與地面的夾角雖有變化,但可通過被動關節抵消這一影響。此外,在控制中只需控制此被動關節中心的軌跡即可。在大型足式機器人中,為節約能量消耗,通常單步步長都較長,足端在一次觸地過程中相對機體運動較遠,被動關節可抵消這一影響,因而在大型足式機器人足端設計中均采用被動關節。而對於小型六足機器人,六條腿的末端只要大致運動形式正確機器人便可行進,腿末端與支撐面產生滑動甚至個別腿末端未與支撐面接觸也不影響機器人工作,因而小型六足機器人在設計中各個驅動關節只要按照預定轉角運行即可,對地面的高低起伏可不做具體調整或進行姿態運算,也不必要設計為被動關節式,故本設計中采用固定式足端。下圖為兩種固定式足端結構的機器人。

圖7 六足機器人

 

 

四、運動學分析

  進行某條擺動腿的運動學分析時,運動學正解求解就是已知機身的位置姿態 和三個轉動關節的大小,求解足端末點的位置坐標。用 D-H 方法在某條腿建立坐標系

圖8 運動學分析

  相鄰關節的 D-H 變換矩陣為:

 

  D-H參數表: 

  得變換矩陣

  運動學逆解的求解就是已知機體的位置姿態和某條腿足端點的位置坐標,求 解這個腿上各個旋轉關節的大小。采用左乘逆變換矩陣的方法,將關節變量分離 出來,從而求得關節轉角

  前面求解運動學正解時,得到了腿部足端點與各個關節角的關系式。對兩邊 進行求導,就得到了足端點的速度與關節角速度的關系

  六足機器人每條腿有 3 個關節,其雅可比矩陣是 6*3 階矩陣,前 3 行代表足 端線速度的傳送比,后 3 行代表足端角速度的傳送比。對於六足機器人的足端, 只需要求出其線速度的傳送比雅克比矩陣

 

 

五、控制系統搭建

1.Arduino控制板


圖9 控制板實物圖

 

2. 24路舵機控制板

 

 

圖10 24路舵機控制板實物圖片

(1)接線端說明

圖11 控制板接線示意圖

  拔掉上圖所示跳線帽是6.4V低壓報警;插上跳線帽是5V低壓報警。低壓報警的時候,電壓越低,滴滴聲的頻率越高,此時請關閉電源開關,給鋰電池充電。跳線帽只會改變蜂鳴器產生低壓報警聲的電壓閾值,不會對控制板有其他功能上的影響。 簡單的理解就是接降壓芯片就要插上跳線帽,不接降壓芯片就不接跳線帽。如果使用的是LDX-218舵機或者LDX-227舵機,那么將下圖所示的跳線帽拔掉;控制板正極可以直接接上7.4V鋰電池供電。


圖12 上位機界面

 (2)上位機軟件及操作教程見網盤:

  鏈接:https://pan.baidu.com/s/1p4YcNMlsagYNA9zjLTiWbg    提取碼:r63r

3. OpenMV

 (1)實物圖

圖13 Openmv 模塊圖

(2)使用教程

  查看網址:https://singtown.com/openmv/

 

 

 

4. 超聲波

 

圖14 超聲波模塊

 

 

5.語音識別

  語音識別模塊圖:

圖16 語音識別模塊

 

 圖17 原理圖

 6.程序

(1)OpenmV程序

 # Untitled - By: 孫寧寧 - 周二 7月 30 2019

import sensor, image, time,lcd, math

sensor.reset()


sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time = 2000)


# Color Tracking Thresholds (L Min, L Max, A Min, A Max, B Min, B Max)
# The below thresholds track in general red/green/blue things. You may wish to tune them...
thresholds = [(32, 78, 27, 5, 57, -15), # generic_red_thresholds
              (30, 100, -64, -8, -32, 32), # generic_green_thresholds
              (0, 15, 0, 40, -80, -20)] # generic_blue_thresholds

lcd.init() # Initialize the lcd screen.

sensor.set_auto_gain(False) # must be turned off for color tracking
sensor.set_auto_whitebal(False) # must be turned off for color tracking

face_cascade = image.HaarCascade("frontalface", stages=25)
eyes_cascade = image.HaarCascade("eye", stages=24)
print(face_cascade, eyes_cascade)

clock = time.clock()

while(True):
    clock.tick()
    img = sensor.snapshot()
    print(clock.fps())
    lcd.display(sensor.snapshot()) # Take a picture and display the image.

    objects = img.find_features(face_cascade, threshold=0.5, scale_factor=1.5)

# Draw faces
    for face in objects:
        img.draw_rectangle(face)
    # Now find eyes within each face.
    # Note: Use a higher threshold here (more detections) and lower scale (to find small objects)
        eyes = img.find_features(eyes_cascade, threshold=0.5, scale_factor=1.2, roi=face)
        for e in eyes:
            img.draw_rectangle(e)
    for blob in img.find_blobs(thresholds, pixels_threshold=200, area_threshold=200):
                # These values depend on the blob not being circular - otherwise they will be shaky.
         if blob.elongation() > 0.5:
               img.draw_edges(blob.min_corners(), color=(255,0,0))
               img.draw_line(blob.major_axis_line(), color=(0,255,0))
               img.draw_line(blob.minor_axis_line(), color=(0,0,255))
                # These values are stable all the time.
         img.draw_rectangle(blob.rect())
         img.draw_cross(blob.cx(), blob.cy())
                # Note - the blob rotation is unique to 0-180 only.
         img.draw_keypoints([(blob.cx(), blob.cy(), int(math.degrees(blob.rotation())))], size=20)

 

(2)藍牙控制六足機器人運動

#include <LobotServoController.h>
LobotServoController myse;
void setup() {
  Serial.begin(9600);
  Serial1.begin(9600);
}

void loop() {

 while(Serial1.available())
 {
      char c = Serial1.read();
      Serial1.println(c);
      if (c=='6')
      {
          while (1)
          {
              ActionGroup(100);
          }
      }
      if (c=='7')
      {
          while(1)
          {
              ActionGroup(150);
          }
      }
      if (c=='8')
      {
          while (1)
          {
                ActionGroup(200);
          }
       }
 }
 }
void ActionGroup(int t)
{
   char c = Serial1.read();
    if(c=='1')
      {
        Serial1.println("forward");
        myse.stopActionGroup();
        delay(200);
        myse.setActionGroupSpeed(21,t);
        delay(200);
        myse.runActionGroup(21,1);
        delay(200);
      } 
    if(c=='2')
      {
        Serial1.println("backward");
        myse.stopActionGroup();
        delay(200);
        myse.setActionGroupSpeed(22,t);
        delay(200);
        myse.runActionGroup(22,1);
        delay(200);
      }
    if(c=='3')
      {
        Serial1.println("shiftleft");
        myse.stopActionGroup();
        delay(200);
        myse.setActionGroupSpeed(23,t);
        delay(200);
        myse.runActionGroup(23,1);
        delay(200);
      }
    if(c=='4')
      {
        Serial1.println("shiftright");
        myse.stopActionGroup();
        delay(200);
        myse.setActionGroupSpeed(24,t);
        delay(200);
        myse.runActionGroup(24,1);
        delay(200);
      }
    if(c=='7')
      {
        Serial1.println("turnleft");
        myse.stopActionGroup();
        delay(200);
        myse.setActionGroupSpeed(27,t);
        delay(200);
        myse.runActionGroup(27,1);
        delay(200);
       }
    if(c=='8')
       {
          Serial1.println("turnright");
          myse.stopActionGroup();
          delay(200);
          myse.setActionGroupSpeed(28,t);
          delay(200);
          myse.runActionGroup(28,1);
          delay(200);
        }
    if(c=='0')
        {
          Serial1.println("stop");
          myse.stopActionGroup();
          delay(200);
          myse.setActionGroupSpeed(20,t);
          delay(200);
          myse.runActionGroup(20,1);
          delay(200);
        }
}

 (3)六足機器人語音控制程序

 
/***************************Sonny 開發****************************
**  工程名稱:語音控制機器人前行后退
** CPU: STC11L08XE
** 晶振:22.1184MHZ
** 波特率:9600 bit/S
**  作者:Sonny
**  修改時間:2019.07.29
/***************************Sonny 開發******************************/
#include "delay.h"
#include "uart.h"
#include "LobotServoController.h"
#include "bool.h"
#include "config.h"
/************************************************************************************/
// nAsrStatus ÓÃÀ´ÔÚmainÖ÷³ÌÐòÖбíʾ³ÌÐòÔËÐеÄ״̬£¬²»ÊÇLD3320оƬÄÚ²¿µÄ״̬¼Ä´æÆ÷
// LD_ASR_NONE:  ±íʾûÓÐÔÚ×÷ASRʶ±ð
// LD_ASR_RUNING£º  ±íʾLD3320ÕýÔÚ×÷ASRʶ±ðÖÐ
// LD_ASR_FOUNDOK:  ±íʾһ´Îʶ±ðÁ÷³Ì½áÊøºó£¬ÓÐÒ»¸öʶ±ð½á¹û
// LD_ASR_FOUNDZERO: ±íʾһ´Îʶ±ðÁ÷³Ì½áÊøºó£¬Ã»ÓÐʶ±ð½á¹û
// LD_ASR_ERROR:  ±íʾһ´Îʶ±ðÁ÷³ÌÖÐLD3320оƬÄÚ²¿³öÏÖ²»ÕýÈ·µÄ״̬
/***********************************************************************************/
uint8 idata nAsrStatus=0;
uint8_t G0_flag=DISABLE;//ÔËÐбêÖ¾£¬ENABLE:ÔËÐС£DISABLE:½ûÖ¹ÔËÐÐ
void MCU_init();
void ProcessInt0(); //ʶ±ð´¦Àíº¯Êý
void  delay(unsigned long uldata);
void  User_handle(uint8 dat);//Óû§Ö´ÐвÙ×÷º¯Êý
void Led_test(void);//µ¥Æ¬»ú¹¤×÷ָʾ
void Delay200ms();
sbit LED=P4^2;//ÐźÅָʾµÆ
//Ó¦ÓÃIO¿Ú¶¨Òå £¨Ä£¿é±ê×¢ P2£©
sbit PA1=P1^0; //¶ÔÓ¦°åÉϱêºÅ P1.0
sbit PA2=P1^1;  //¶ÔÓ¦°åÉϱêºÅ P1.1
sbit PA3=P1^2;  //¶ÔÓ¦°åÉϱêºÅ P1.2
sbit PA4=P1^3;  //¶ÔÓ¦°åÉϱêºÅ P1.3
sbit PA5=P1^4;  //¶ÔÓ¦°åÉϱêºÅ P1.4
sbit PA6=P1^5;  //¶ÔÓ¦°åÉϱêºÅ P1.5
sbit PA7=P1^6;  //¶ÔÓ¦°åÉϱêºÅ P1.6
sbit PA8=P1^7;  //¶ÔÓ¦°åÉϱêºÅ P1.7
/***********************************************************
 int main(void)
 {
 int i = 0;
  SystemInit();//ϵͳʱÖӵȳõʼ»¯
 delay_init(72);      //ÑÓʱ³õʼ»¯
 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//ÉèÖÃNVICÖжϷÖ×é2:2λÇÀÕ¼ÓÅÏȼ¶£¬2λÏìÓ¦ÓÅÏȼ¶
  uartInit(9600);//´®¿Ú³õʼ»¯Îª9600
  uint8 idata nAsrRes;
 uint8 i=0;
 Led_test();
 MCU_init();
 LD_Reset();
 UartIni(); /*´®¿Ú³õʼ»¯*/
 nAsrStatus = LD_ASR_NONE;  // ³õʼ״̬£ºÃ»ÓÐÔÚ×÷ASR
 #ifdef TEST 
 PrintCom("Ò»¼¶¿ÚÁСÄþ\r\n"); /*text.....*/
 PrintCom("¶þ¼¶¿ÚÁ1.ǰ½ø\r\n"); /*text.....*/
 PrintCom(" 2.ºóÍˤ\r\n"); /*text.....*/
 PrintCom(" 3.×óÒÆ\r\n"); /*text.....*/
 PrintCom(" 4.ÓÒÒÆ\r\n"); /*text.....*/
 PrintCom("  5.ÕÅ×ì\r\n"); /*text.....*/
 PrintCom(" 6.ҧס\r\n"); /*text.....*/
 PrintCom(" 7.×óת\r\n"); /*text.....*/
 PrintCom(" 8.ÓÒת\r\n"); /*text.....*/
 PrintCom(" 0.ÔÝÍ£\r\n"); /*text.....*/
 #endif
 while(1){
  
  receiveHandle(); //½ÓÊÕ´¦Àí
  delay_ms(1);
  i++;
  if(i ==2000)
   getBatteryVoltage(); //·¢ËÍ»ñÈ¡µç³ØµçѹָÁî
  if(i == 3000) { 
   printf("Bvolt:%d mv\r\n",batteryVolt); //´òÓ¡µç³Øµçѹ
   i = 0;
 }
  switch(nAsrStatus)
  {
   case LD_ASR_RUNING:
   case LD_ASR_ERROR:  
    break;
   case LD_ASR_NONE:
   {
    nAsrStatus=LD_ASR_RUNING;
    if (RunASR()==0) /* Æô¶¯Ò»´ÎASRʶ±ðÁ÷³Ì£ºASR³õʼ»¯£¬ASRÌí¼Ó¹Ø¼ü´ÊÓÆô¶¯ASRÔËËã*/
    {
     nAsrStatus = LD_ASR_ERROR;
    }
    break;
   }
   case LD_ASR_FOUNDOK: /* Ò»´ÎASRʶ±ðÁ÷³Ì½áÊø£¬È¥È¡ASRʶ±ð½á¹û*/
   {    
    nAsrRes = LD_GetResult();  /*»ñÈ¡½á¹û*/
    User_handle(nAsrRes);//Óû§Ö´Ðк¯Êý
    nAsrStatus = LD_ASR_NONE;
    break;
   }
   case LD_ASR_FOUNDZERO:
   default:
   {
    nAsrStatus = LD_ASR_NONE;
    break;
   }
  }// switch     
 }// while
}
/***********************************************************
* Ãû    ³Æ£º   LEDµÆ²âÊÔ
* ¹¦    ÄÜ£º µ¥Æ¬»úÊÇ·ñ¹¤×÷ָʾ
* Èë¿Ú²ÎÊý£º ÎÞ
* ³ö¿Ú²ÎÊý£ºÎÞ
* ˵    Ã÷£º      
**********************************************************/
void Led_test(void)
{
 LED=~ LED;
 Delay200ms();
 LED=~ LED;
 Delay200ms();
 LED=~ LED;
 Delay200ms();
 LED=~ LED;
 Delay200ms();
 LED=~ LED;
 Delay200ms();
 LED=~ LED;
}
/***********************************************************
* Ãû    ³Æ£º void MCU_init()
* ¹¦    ÄÜ£º µ¥Æ¬»ú³õʼ»¯
* Èë¿Ú²ÎÊý£º 
* ³ö¿Ú²ÎÊý£º
* ˵    Ã÷£º      
* µ÷Ó÷½·¨£º
**********************************************************/
void MCU_init()
{
 P0 = 0xff;
 P1 = 0x00;
 P2 = 0xff;
 P3 = 0xff;
 P4 = 0xff;
 P1M1=0;
 P1M0=0xff;
 LD_MODE = 0;  // ÉèÖÃMD¹Ü½ÅΪµÍ£¬²¢ÐÐģʽ¶Áд
 IE0=1;
 EX0=1;
 EA=1;
}
/***********************************************************
* Ãû    ³Æ£º ÑÓʱº¯Êý
* ¹¦    ÄÜ£º
* Èë¿Ú²ÎÊý£º 
* ³ö¿Ú²ÎÊý£º
* ˵    Ã÷£º      
* µ÷Ó÷½·¨£º
**********************************************************/
void Delay200us()  //@22.1184MHz
{
 unsigned char i, j;
 _nop_();
 _nop_();
 i = 5;
 j = 73;
 do
 {
  while (--j);
 } while (--i);
}
void  delay(unsigned long uldata)
{
 unsigned int j  =  0;
 unsigned int g  =  0;
 while(uldata--)
 Delay200us();
}
void Delay200ms()  //@22.1184MHz
{
 unsigned char i, j, k;
 i = 17;
 j = 208;
 k = 27;
 do
 {
  do
  {
   while (--k);
  } while (--j);
 } while (--i);
}
/***********************************************************
* Ãû    ³Æ£º Öжϴ¦Àíº¯Êý
* ¹¦    ÄÜ£º
* Èë¿Ú²ÎÊý£º 
* ³ö¿Ú²ÎÊý£º
* ˵    Ã÷£º      
* µ÷Ó÷½·¨£º
**********************************************************/
void ExtInt0Handler(void) interrupt 0 
{  
 ProcessInt0();    /* LD3320 ËͳöÖжÏÐźţ¬°üÀ¨ASRºÍ²¥·ÅMP3µÄÖжϣ¬ÐèÒªÔÚÖжϴ¦Àíº¯ÊýÖзֱð´¦Àí*/
}
/***********************************************************
* Ãû    ³Æ£ºÓû§Ö´Ðк¯Êý
* ¹¦    ÄÜ£ºÊ¶±ð³É¹¦ºó£¬Ö´Ðж¯×÷¿ÉÔڴ˽øÐÐÐÞ¸Ä
* Èë¿Ú²ÎÊý£º ÎÞ
* ³ö¿Ú²ÎÊý£ºÎÞ
* ˵    Ã÷£º ͨ¹ý¿ØÖÆPAx¶Ë¿ÚµÄ¸ßµÍµçƽ£¬´Ó¶ø¿ØÖÆÍⲿ¼ÌµçÆ÷µÄͨ¶Ï     
**********************************************************/
void  User_handle(uint8 dat)
{
     //UARTSendByte(dat);//´®¿Úʶ±ðÂ루ʮÁù½øÖÆ£©
   if(0==dat)
   {
     G0_flag=ENABLE;
    LED=0;
   }
   else if(ENABLE==G0_flag)
   { 
     G0_flag=DISABLE;
    LED=1;
    switch(dat)     /*¶Ô½á¹ûÖ´ÐÐÏà¹Ø²Ù×÷,¿Í»§ÐÞ¸Ä*/
     {
      case CODE_QJ:   /*ÃüÁî¡°²âÊÔ¡±*/
      PrintCom("¡°Ç°½ø¡±ÃüÁîʶ±ð³É¹¦\r\n"); //´®¿ÚÊä³öÌáʾÐÅÏ¢
       runActionGroup(1, 1); //ÔËÐÐ1ºÅ¶¯×÷×é1´Î
       delay_ms(1500);
       stopActionGroup();  //Í£Ö¹¶¯×÷×éÔËÐÐ
       runActionGroup(1, 1); //ÔËÐÐ1ºÅ¶¯×÷×é1´Î
              break;
     case CODE_HT:  /*ÃüÁî¡°È«¿ª¡±*/
      PrintCom("¡°ºóÍË¡±ÃüÁîʶ±ð³É¹¦\r\n");//´®¿ÚÊä³öÌáʾÐÅÏ¢
      runActionGroup(2, 1); //ÔËÐÐ2ºÅ¶¯×÷×é1´Î
       delay_ms(1500);
       stopActionGroup();  //Í£Ö¹¶¯×÷×éÔËÐÐ
              break;
     case CODE_ZY:  /*ÃüÁî¡°¸´Î»¡±*/    
      PrintCom("¡°×óÒÆ¡±ÃüÁîʶ±ð³É¹¦\r\n"); //´®¿ÚÊä³öÌáʾÐÅÏ¢
      runActionGroup(3, 1); //ÔËÐÐ3ºÅ¶¯×÷×é1´Î
       delay_ms(1500);
       stopActionGroup();  //Í£Ö¹¶¯×÷×éÔËÐÐ
       setActionGroupSpeed(1, 200);//½«1ºÅ¶¯×÷×éÔËÐÐËÙ¶ÈÉèÖÃΪ200%
       runActionGroup(1, 1); //ÔËÐÐ1ºÅ¶¯×÷×é1´Î
             break;
     case CODE_YY:  /*ÃüÁî¡°¸´Î»¡±*/    
      PrintCom("¡°ÓÒÒÆ¡±ÃüÁîʶ±ð³É¹¦\r\n"); //´®¿ÚÊä³öÌáʾÐÅÏ¢
      runActionGroup(4, 1); //ÔËÐÐ4ºÅ¶¯×÷×é1´Î
       delay_ms(1500);
       stopActionGroup();  //Í£Ö¹¶¯×÷×éÔËÐÐ
             break;
     case CODE_ZZ:  /*ÃüÁî¡°¸´Î»¡±*/    
      PrintCom("¡°×óת¡±ÃüÁîʶ±ð³É¹¦\r\n"); //´®¿ÚÊä³öÌáʾÐÅÏ¢
      runActionGroup(7, 1); //ÔËÐÐ7ºÅ¶¯×÷×é1´Î
       delay_ms(1500);
       stopActionGroup();  //Í£Ö¹¶¯×÷×éÔËÐÐ
             break;
     case CODE_YZ:  /*ÃüÁî¡°¸´Î»¡±*/    
      PrintCom("¡°ÓÒת¡±ÃüÁîʶ±ð³É¹¦\r\n"); //´®¿ÚÊä³öÌáʾÐÅÏ¢
      runActionGroup(8, 1); //ÔËÐÐ8ºÅ¶¯×÷×é1´Î
       delay_ms(1500);
       stopActionGroup();  //Í£Ö¹¶¯×÷×éÔËÐÐ
             break;
     case CODE_ZT:  /*ÃüÁî¡°¸´Î»¡±*/    
      PrintCom("¡°ÔÝÍ£¡°ÃüÁîʶ±ð³É¹¦\r\n"); //´®¿ÚÊä³öÌáʾÐÅÏ¢
      runActionGroup(0, 1); //ÔËÐÐ0ºÅ¶¯×÷×é1´Î
       delay_ms(1500);
       stopActionGroup();  //Í£Ö¹¶¯×÷×éÔËÐÐ
             break;                           
     case CODE_ZK:  /*ÃüÁî¡°¸´Î»¡±*/    
      PrintCom("¡°ÕÅ¿ª¡°ÃüÁîʶ±ð³É¹¦\r\n"); //´®¿ÚÊä³öÌáʾÐÅÏ¢
      runActionGroup(5, 1); //ÔËÐÐ5ºÅ¶¯×÷×é1´Î
       delay_ms(1500);
       stopActionGroup();  //Í£Ö¹¶¯×÷×éÔËÐÐ
             break;    
     case CODE_YH:  /*ÃüÁî¡°¸´Î»¡±*/    
      PrintCom("¡°Ò§ºÏ¡°ÃüÁîʶ±ð³É¹¦\r\n"); //´®¿ÚÊä³öÌáʾÐÅÏ¢
      runActionGroup(6, 1); //ÔËÐÐ6ºÅ¶¯×÷×é1´Î
       delay_ms(1500);
       stopActionGroup();  //Í£Ö¹¶¯×÷×éÔËÐÐ
             break;    
     default:PrintCom("ÇëÖØÐÂʶ±ð·¢¿ÚÁî\r\n"); //´®¿ÚÊä³öÌáʾÐÅÏ
             break;
    } 
   } 
   else  
   {
    PrintCom("Çë˵³öÒ»¼¶¿ÚÁî\r\n"); //´®¿ÚÊä³öÌáʾÐÅÏ¢£¨¿Éɾ³ý£© 
   }

 

六、實物制作

 1.加工件明細表

零件名稱

數量

厚度

大腿版前側

6

3mm

大腿版外側

6

3mm

底板

1

3mm

底板下

1

3mm

小腿版兩側

12

3mm

支撐

6

3mm

夾爪固定端

1

3mm

 2.外購件清單

名稱

數量

價格

淘寶鏈接

舵機

18 1761 https://item.taobao.com/item.htm?spm=a1z09.2.0.0.158a2e8dfZR5nf&id=23334420583&_u=ue2uapoac1a
24路舵機控制板 1 138 https://item.taobao.com/item.htm?spm=a1z09.2.0.0.158a2e8dfZR5nf&id=521728033704&_u=ue2uapo81b2
機械夾爪 1 140 https://m.tb.cn/h.e6vxWHd?sm=db9dee
鋁板加工費 附表 430 https://item.taobao.com/item.htm?spm=a1z09.2.0.0.6d6d2e8dz2okDx&id=570777216949&_u=ae2uapo0ef4 
銅柱 24 19.98 略 
OPENmv 1 247.88  

https://item.taobao.com/item.htm?spm=a1z09.2.0.0.386e2e8d5j93fe&id=557245458884&_u=uai92kkcb0d

語音識別模塊 1 83 https://m.tb.cn/h.ehCi7R3?sm=8d8524 
16路舵機控制板 2 204 https://item.taobao.com/item.htm?spm=a1z09.2.0.0.158a2e8dfZR5nf&id=521728033704&_u=ue2uapo81b2 

 3.實物拼裝圖

 

圖18 實物圖

4.參數表

參數

數值

含義

a

142.18

基體中心距中間腿關節距離

b 159.12

基體中心距前腿關節水平距離

c 113.27

基體中心距前腿關節豎直距離

d 60.74

大腿基節長度

e 121.97

大腿長度

f 165.53

小腿長度

 

七、步態算法分析

1.六足機器人常見步態

(1)二步態

  二步態也叫三足步態、三角步態。支撐狀態為 L1、L3、L5 和 L2、L4、L6腿 交替支撐。行走示意圖和步態相圖如圖所示,示意圖中紅色連桿表示支撐腿,步態相圖中黑色實心部分表示支撐相。

圖19  三足步態示意圖

 

(2)三步態

  三步態情況下始終有四條腿作為支撐相。通常將 L1、 L5 分為一組,L2、 L4 分為一組,L3、 L6 分為一組,也可按照其它方式兩兩分組。移動時每組腿依次抬起擺動。因支撐平面為四邊形,因而又稱之為四足步態或四角步態。其行走示意圖如下:


圖20 四足步態示意圖

(3)六步態

  六步態情況下每條腿各自為一個分組,依次抬起進行擺動。其抬起順序變化相比於三步態更多,可以為 L1 -L6 -L2 -L5 -L3 -L4 也可以是 L1 -L4 -L2 -L6 -L3 -L5不同的邁步方式使得機器人在整個運動周期內的支撐平面以不同的方式變化,以便適應不同的越障或爬坡需求。其行走示意圖如下:


圖21 六步態示意圖

 

2.六足機器人工況分析

  平路二步態工況指的是六足機器人在水平地面上以二步態方式行走的工況。此種工況處於支撐相的腿數目最少,因而單腿和整機受垂向力最大。對於機架來說支撐點最少,最不穩定。對於單腿來說,尤其是單獨在一側支撐的單腿,其一條腿就支撐了整機約為一半的重量,加上沖擊等因素此條腿承受的豎直力還要更多。暫設其受力系數為 1.5 倍,考慮到整機質量約為 3 t,得到單側支撐相足端沖擊約為 22500 N。

 

 圖22 平路二步態

  縱坡二步態足端受沿機體方向的最大縱向力。受縱向力數值與坡面角度有關。當縱向力最大時機體與坡面平行且足端支撐形式與平路二步態相同,即不采取姿態補償措施。按照設計要求,最大縱坡角度為 30°。整機全重 3 t,單側腿受力約為 1.5 t,分解成沿坡面力 7500 N,垂直坡面力 12990 N。

圖23 縱坡二步態 

 3.MATLAB步態算法

MATLAB機器人工具箱下載地址:http://petercorke.com/wordpress/toolboxes/robotics-toolbox

 (1)運動分析

  第一步:建立坐標系,做模型  

 

   第二步:經過變換,則M點相對於坐標

 

 

 變換矩陣:

 

  六足機器人基體的尺寸及各部分腿的編號:

 

MATLAB代碼:

clear
clc
L1=60.74;%大腿與身體的長
L2=121.97;%大腿長
L3=165.53;%小腿長
a=305; %六邊形邊長
theta=[-120 -60 0 60 120 -180].*pi./180; %關節與基體的轉角
origin=[340;0;0;1];% 初始位置,即足部移動340的距離
t=[a/2;-sqrt(3)*a/2;0];%水平方向偏移量,即腿關節距形體中心的位移
R=cell(1,6);% R為6個元素的元胞組
T=cell(1,6);% R為6個元素的元胞組
for i=1:6;
    R{i}=[cos(theta(i)),-sin(theta(i)),0; sin(theta(i)),cos(theta(i)),0;0,0,1];%旋轉矩陣
    T{i}=[R{i},t;0 0 0 1];%變換矩陣
end
Trans=cell(1,6);
for i=1:6
    Trans{i}=T{i}*origin;
end
alpha=[0 0 0 0 0 0];
beta=[0 0 0 0 0 0];
gamma=[0 0 0 0 0 0];
phi=[0 0 0 0 0 0];
K1=[0 0 0 0 0 0];
K2=[0 0 0 0 0 0];
for i =1:6
    alpha(i)=(atan(Trans{i}(2)/Trans{i}(1)));%α值,基節轉角
    if(alpha(i)>0)
        alpha(i)=alpha(i);
    else
        alpha(i)=alpha(i)+pi;
    end
    K1(i)=Trans{i}(1)/cos(alpha(i))-L1;
    K2(i)=Trans{i}(3);
    gamma(i)=(acos((K1(i)^2+K2(i)^2-L2^2-L3^2)/(2*L2*L3)));% γ值,小腿外轉角
    phi(i)=atan(L3*sin(gamma(i))/(L2+L3*cos(gamma(i))));%φ值
    beta(i)=asin(K2(i)/(sqrt(L2+L3*cos(gamma(i)))^2+(L3*sin(gamma(i)))^2))-phi(i);%β值,大腿轉角
  
    alphi(i)=alpha(i)*180/pi;%變換為角度
    beta(i)=beta(i)*180/pi;%變換為角度
    gamma(i)=gamma(i)*180/pi;%變換為角度
end
 
        

(2)simScape仿真動畫:

1.支持包和安裝插件下載

下載地址:https://ww2.mathworks.cn/campaigns/offers/download_smlink_confirmation.html?elqsid=1564535708654&potential_use=Student

2.安裝教程

https://ww2.mathworks.cn/help/physmod/smlink/ug/installing-and-linking-simmechanics-link-software.html

1以管理員身份打開MATLAB,選擇當前文件夾為下載的安裝包路徑;

2)控制台輸入:install_addon('smlink.r2017b.win64.zip')

3)在MATLAB命令行窗口輸入 regmatlabserver

4啟動服務器后,激活Solidwork的MATLAB物理建模插件

a.在MATLAB命令行窗口輸入:smlink_linksw

 

b.啟動SW

c.找到工具菜單選擇添加插件,選擇Simscape Multibody Link

 仿真動畫程序:

  仿真示意圖:

 

 

 

 

八、六足機器人的步行效率實驗

1.不同足部結構對過障能力的實驗探究

(1)實驗問題:

  本實驗設定六足機器人所處環境分別為草窪地和斜沙坡兩種環境,並在兩種環境下分別測試評價不同足部結構的過障能力

 

(2)實驗參數:

 

    自變量:足部結構i,i=1表示足部結構與地面為點接觸;i=2 表示足部結構與地面為線接觸、i=3表示足部結構與地面為面接觸。

    因變量:六足機器人的過障能力 W

    不變量:六足機器人的自重M、除腳步結構外的其他結構L、控制方式C、行走姿態Z、供電功率P

    忽略因素:除地面環境變化外的其他環境變量,如環境溫度、風力等;不考慮電池和機械結構在屢次實驗中的耗損和折舊;

(3)實驗方式:

 

    足部結構的設計方式:對於點接觸,機構初始狀態即為點接觸,腳步結構為弧形形狀,與地面接觸面為點接觸;

              對於線接觸,機構足部每只腳由兩塊鋁板構成,每塊鋁板底部為點接觸,用膠帶或細長物連接即可實現

              對於面接觸,機構足部用海綿、泡沫塊等大面積物質固定,保證接觸地面為面接觸即可

    過障能力的評價指標:a.是否能夠完全通過障礙 Y

              b.越過障礙耗電量的大小 V

              c.越過障礙的耗時多少 T

(4)科學性分析:

  六足機器人較其他移動機器人而言,最大的優勢在於其多足結構可以適應多種復雜地形,故而越障能力對於六足機器人而言顯得至關重要。對於越障而言,優先考慮的是能夠通過障礙;其次是通過障礙所消耗能源的多少;最后是通過障礙花費的時間的多少。這三個評價指標涵蓋了移動平台在越障中的關鍵因素,從功能的完整性、耗能、效率等三方面進行考慮,符合現實場景中六足機器人的應用痛點,研究性十分具有價值和意義。

  其次,在設計中發現足部結構的改變對越障能力有着很大的影響,在同樣的基體結構、能源供給、環境條件下,面接觸的足部結構可能更便於越障,故此處將足部結構作為變量進行試驗論證,並對比不同環境下的數據結果,研究論證“面接觸式的足部結構可更好適應全部環境”或是“某種環境條件面接觸式足部結構更適應全部環境”等觀點。

(5)實驗數據、結果(待續)

2.不同步態對移動速度的實驗探究

(1)實驗問題:

  本實驗設定六足機器人存在三角步態、四角步態、六角步態三種典型步態,並在滿足步態穩定的前提下對其在平地的移動速度進行分析比較,並得出最高效的行走步態方案。

(2)實驗參數

  自變量:六足機器人的步態模式

  因變量:六足機器人的移動速度

  無關變量:六足機器人的自重、地面環境、機械結構

  忽略因素:除地面環境變化外的其他環境變量,如環境溫度、風力等;不考慮電池和機械結構在屢次實驗中的耗損和折舊;

(3)實驗方式

    步態模式由24路舵機控制板通過上位機界面編程更換不同模式,並在不同模式下進行試驗。

   a.三角步態為:

 

   b.四角步態為:

 

   c.六角步態為:

 

 

  其次,六足機器人移動速度的評價指標

   a.以固定距離內,六足機器人從起點出發至到達終點所用時間作為速度指標

   b.在同樣距離內,不同步態所消耗的電量

(4)科學性分析

  六足機器人優勢在於可適應性強,但其劣勢在於移動速度較慢,故而在滿足可適應的條件下使其移動速度最大化,是六足機器人發展的必要研究方向,對六足的野外搜救、偵察等應用中發揮很大的作用。

  六足機器人對移動速度的影響因素包括很多,如供電功率、行走機構、步態模式等,此處選取步態模式作為研究對象,仿照自然界中的昆蟲、哺乳兩大類典型的爬行步態進行試驗,測試選取移動速度最佳的方案,仿生學的基礎上保證了一定的科學性。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM