雙足機器人簡單步態生成

  ?讓機器人行走最簡單的方法是先得到一組步態曲線,即腿部每個關節隨時間運動的角度值。可以在ADAMS或3D Max、Blender等軟件中建立好機構/骨骼模型,設計出腳踝和髖關節的運動曲線,然后進行逆運動學解算,測量每個關節在運動過程中的轉角,最后將得到的曲線導出。拿到曲線數據后我們就可以用單片機讀取,然后發送給機器人的舵機去執行運行。這種方法的缺點是機器人只能按照固定的步態行走,不夠靈活,比如抬腳高度、步長等參數都是定死的,如果需要修改還得再使用別的軟件導出新的步態數據。

  最簡單的腿部結構如下圖所示,在髖關節、膝關節和踝關節各有一個轉動自由度,可以通過三角形余弦定理求得機構的運動學逆解。這種機器人只能在矢狀面上直線前進,不能轉彎。對行走過程進行一定的簡化和假設:

1. 髖關節始終保持恒定的高度(實際上會有微小的波動)

2. 機器人腳面始終平行于地面

  為了確定每個關節的角度,需要設計行走過程中踝關節點的運動軌跡。這里采用簡單的正弦曲線作為其軌跡(也可以采用樣條曲線、Bézier 曲線等),正弦曲線的幅值對應抬腳最大高度。

?

  在Python中實現導入雙腿模型文件,生成指定的步態數據后讓其循環運動,就可以模擬機器人行走。代碼如下(很糙...只是實現了基本功能,細節還有待完善)

#!/usr/bin/env python
import vtk
import math
from vtk.util.colors import *
import numpy as np
import timeactor  = list()   # the list of links
filenames = ["link-1.stl","link-2.stl","link-3.stl","link-4.stl","link-5.stl","link-6.stl"]
renWin = vtk.vtkRenderWindow()joint1 = vtk.vtkAssembly()
joint2 = vtk.vtkAssembly()
joint3 = vtk.vtkAssembly()
joint4 = vtk.vtkAssembly()
joint5 = vtk.vtkAssembly()
joint6 = vtk.vtkAssembly()ThighLength = 100.0
ShankLength = 100.0
HipHeight = 180.0
FootLift = 10
StrideLength = 60
Subdivision = 20leg_joint = np.zeros(3, dtype=np.float)
patterns = np.zeros((2*Subdivision ,6), dtype=np.float)
_p = 0txt = vtk.vtkTextActor()
distance = 0.0def Rad2Deg(rad):return  rad * 180.0 / math.pidef FootHeight(x): return (HipHeight - FootLift * math.cos(abs(x * math.pi / StrideLength)))def LegIK(x, y):global leg_jointdist = math.sqrt(x**2 + y**2)leg_joint[0] = math.acos(dist / (2 * ShankLength)) + math.atan2(x, y)leg_joint[1] = math.pi - math.acos((ThighLength**2 + ShankLength**2 - dist**2) / (2 * ThighLength* ShankLength))leg_joint[2] = leg_joint[1] - leg_joint[0]def GenerateGait():global leg_jointglobal patterns# Move left leg forward.  for i in range(Subdivision):x = (i - Subdivision/2) * (StrideLength / Subdivision)y = FootHeight(x)        LegIK(x, y)            patterns[i, :3] = Rad2Deg(leg_joint)# Move left leg backward.  for i in range(Subdivision):x = (Subdivision/2 - i) * (StrideLength / Subdivision)y = HipHeightLegIK(x, y)                patterns[i+Subdivision, :3] = Rad2Deg(leg_joint)  # Build right leg from phase shift clone of left. for i in range(2*Subdivision):patterns[i, 3:] = -patterns[(i + Subdivision) % (2*Subdivision), :3]# Customize vtkInteractorStyleTrackballCamera 
class MyInteractor(vtk.vtkInteractorStyleTrackballCamera):def __init__(self,parent=None):self.AddObserver("CharEvent",self.OnCharEvent)self.AddObserver("KeyPressEvent",self.OnKeyPressEvent)def OnCharEvent(self,obj,event):passdef OnKeyPressEvent(self,obj,event):global _pglobal distance# Get the compound key strokes for the eventkey = self.GetInteractor().GetKeySym()GenerateGait()if(key == "Return"):# start animationjoint1.SetPosition(0, 0, HipHeight-ThighLength-ShankLength)joint4.SetPosition(0, 0, HipHeight-ThighLength-ShankLength)if (_p == 2*Subdivision):_p = 0joint1.SetOrientation(0, -patterns[_p][0], 0)joint2.SetOrientation(0, patterns[_p][1], 0)joint3.SetOrientation(0, -patterns[_p][2], 0)joint4.SetOrientation(0, patterns[_p][3], 0)joint5.SetOrientation(0, -patterns[_p][4], 0)joint6.SetOrientation(0, patterns[_p][5], 0)_p = _p + 1distance = distance + StrideLength/(2 * Subdivision * 1000.0)txt.SetInput("Distance: " + str(distance) + "m")renWin.Render()returndef CreateCoordinates():# create coordinate axes in the render windowaxes = vtk.vtkAxesActor() axes.SetTotalLength(40, 40, 40)  # Set the total length of the axes in 3 dimensions # Set the type of the shaft to a cylinder:0, line:1, or user defined geometry. 
    axes.SetShaftType(0) transform = vtk.vtkTransform() transform.Translate(0.0, 0.0, 200.0)axes.SetUserTransform(transform)axes.SetCylinderRadius(0.02) axes.GetXAxisCaptionActor2D().SetWidth(0.03) axes.GetYAxisCaptionActor2D().SetWidth(0.03) axes.GetZAxisCaptionActor2D().SetWidth(0.03) return axesdef CreateGround():# create plane sourceplane = vtk.vtkPlaneSource()plane.SetXResolution(20)plane.SetYResolution(20)plane.SetCenter(0,0,0)plane.SetNormal(0,0,1)# mappermapper = vtk.vtkPolyDataMapper()mapper.SetInputConnection(plane.GetOutputPort())# actoractor = vtk.vtkActor()actor.SetMapper(mapper)actor.GetProperty().SetRepresentationToWireframe()actor.GetProperty().SetColor(light_grey)transform = vtk.vtkTransform()transform.Scale(400,400,1)actor.SetUserTransform(transform)return actordef LoadSTL(filename):reader = vtk.vtkSTLReader()reader.SetFileName(filename)mapper = vtk.vtkPolyDataMapper() # maps polygonal data to graphics primitives
    mapper.SetInputConnection(reader.GetOutputPort())actor = vtk.vtkLODActor() actor.SetMapper(mapper)return actor   # represents an entity in a rendered scenedef CreateScene():# Create a rendering window and rendererren = vtk.vtkRenderer()renWin.AddRenderer(ren)# Create a renderwindowinteractoriren = vtk.vtkRenderWindowInteractor()iren.SetRenderWindow(renWin)style = MyInteractor()style.SetDefaultRenderer(ren)iren.SetInteractorStyle(style)for id, file in enumerate(filenames):actor.append(LoadSTL(file))r = vtk.vtkMath.Random(.4, 1.0)g = vtk.vtkMath.Random(.4, 1.0)b = vtk.vtkMath.Random(.4, 1.0)actor[id].GetProperty().SetDiffuseColor(r, g, b)actor[id].GetProperty().SetDiffuse(.8)actor[id].GetProperty().SetSpecular(.5)actor[id].GetProperty().SetSpecularColor(1.0,1.0,1.0)actor[id].GetProperty().SetSpecularPower(30.0)joint1.AddPart(actor[0])joint1.AddPart(joint2)joint2.AddPart(actor[1])joint2.AddPart(joint3)joint3.AddPart(actor[2])joint4.AddPart(actor[3])joint4.AddPart(joint5)joint5.AddPart(actor[4])joint5.AddPart(joint6)joint6.AddPart(actor[5])joint1.SetOrigin(0, 0, 200)joint4.SetOrigin(0, 0, 200)joint2.SetOrigin(0, 0, 100)joint5.SetOrigin(0, 0, 100)ren.AddActor(joint1)ren.AddActor(joint4)# Add coordinatesaxes = CreateCoordinates()ren.AddActor(axes)# Add groundground = CreateGround()ren.AddActor(ground)# create a text actortxt.SetInput("Distance: 0m")txtprop=txt.GetTextProperty()txtprop.SetFontFamilyToArial()txtprop.SetFontSize(18)txtprop.SetColor(1,1,1)txt.SetDisplayPosition(450,550)# assign actor to the renderer
    ren.AddActor(txt)# Set background colorren.SetBackground(.1, .1, .1)# Set window sizerenWin.SetSize(600, 600)# Enable user interface interactor
    iren.Initialize()iren.Start()if __name__ == "__main__":CreateScene()
View Code

  按住回車鍵,一幀一幀播放動畫。最后的效果是這樣的:

?

?

參考:

https://github.com/Rhoban/IKWalk

Using Inverse Kinematics to Develop a Biped Robot Walking Gait C#

8 DOF Biped Robot using Dynamixel AX-12A Servos and Arduino

轉載于:https://www.cnblogs.com/21207-iHome/p/6052159.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/372699.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/372699.shtml
英文地址,請注明出處:http://en.pswp.cn/news/372699.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

重新訪問了訪客模式

訪客模式是面向對象設計中最被高估但又被低估的模式之一。 高估了它,因為它常常被選擇得太快( 可能是由建筑宇航員選擇的 ),然后以錯誤的方式添加時會膨脹本來非常簡單的設計。 如果您不遵循教科書示例,那么它可能會非…

java web開發技術大_2021年六大javaweb開發主流技術

作為歷史最為悠久的編程語言——java,歷經數十年依然盤踞在編程榜最前面的位置,這與它的技術和應用范圍是分不開的,同時呢,javaweb開發主流技術更是java開發者時時刻刻關注的問題,接下來我們一起分析一下2020年互聯網行…

ASP.NET—013:實現帶控件的彈出層(彈出框)

http://blog.csdn.net/yysyangyangyangshan/article/details/38458169 在頁面中用到彈出新頁面的情況比較多的,一般來說都是使用JS方法showModalDialog("新頁面相對路徑?參數1&參數2",window,"新頁面樣式");然后會新彈出一個模態的page頁。…

運維人員日常工作(轉自老男孩)

1)運維人員要謹記的6個字: 運維人員做事需遵循:簡單、易用、高效 (2)運維人員服務的3大宗旨: 1、企業數據安全保障。 2、7*24小時業務持續提供服務。 3、不斷提升用戶感受、體驗。 (3&#xff0…

c# 操作DatatTable

dtTemp.Columns.Add("列名");//增加一列 dtTemp.Columns.Remove("列名");//刪除一列 dtTemp.Columns["舊列名"].ColumnName "新列名";//修改列名 dtTemp.Columns["列名1"].SetOrdinal(dtTemp.Columns["列名2"].O…

java 二進制 歸屬權限_【Java EE 學習 75 上】【數據采集系統第七天】【二進制運算實現權限管理】【權限分析和設計】...

一、權限計算相關分析1.如何存儲權限首先說一下權限保存的問題,一個系統中最多有多少權限呢?一個大的系統中可能有成百上千個權限需要管理。怎么保存這么多的權限?首先,我們使用一個數字中的一位保存一種權限,那么如果…

MongoDB性能測試

因此,今天早上,我在mongo shell中四處亂逛。 我想出了三種不同的方式來聚合所需的數據,但不確定隨后應移植哪種代碼以在應用程序中使用。 那么,我將如何決定實施哪種方法呢? 好吧,讓我們選擇性能最佳的產品…

$_SERVER[SCRIPT_NAME]、$_SERVER[PHP_SELF]、$_SERVER[QUERY_STRING]、$_SERVER[REQUEST_URI]

1、$_SERVER["SCRIPT_NAME"] 說明:包含當前腳本的路徑 2、$_SERVER["PHP_SELF"] 說明:當前正在執行腳本的文件名 3、$_SERVER["QUERY_STRING"] 說明:查詢(query)的字符串 4、$_SERVER["REQUEST_URI"…

yii2增刪改查及AR的理解

yii2增刪改查 // 返回 id 為 1 的客戶 $customer Customer::findOne(1); // 返回 id 為 1 且狀態為 *active* 的客戶 $customer Customer::findOne([ id > 1, status > Customer::STATUS_ACTIVE, ]); // 返回id為1、2、3的一組客戶 $customers Customer::findAll([1, …

GWT和HTML5 Canvas演示

這是我對GWT和HTML5 Canvas的第一個實驗。 我的第一個嘗試是創建矩形,僅用幾行代碼就得出了這樣的內容: 碼: public class GwtHtml5 implements EntryPoint {static final String canvasHolderId "canvasholder";static final St…

mysql 平均值 排序_MySQL按平均兩個平均值排序

我正在競賽網站上工作,有兩種類型的用戶,普通網站成員和評委.每個人都可以使用拖放工具按照他們選擇的順序對特定比賽中的條目進行排序.完成后,相關的條目ID將附加一個排名值,然后可用于確定比賽中哪個條目獲得最高的平均分數.獲勝者實際上將通過平均每組的平均值來確定.我希望…

Solr管理界面詳解

轉載于:https://www.cnblogs.com/gslblog/p/6553813.html

iconv編碼轉換指令

看到一個不錯的指令iconv,可以對文件編碼進行轉換,記錄如下: iconv --list 列出所有支持轉換的編碼 icon -f code1 -t code2 filename -o newfile -f 即from 原來的編碼 -t 即to 新的編碼 filename 待轉換的文件名 -o newfile 要輸出的文件名 轉載于:htt…

使用Spring Roo進行快速云開發–第2部分:VMware Cloud Foundry

Spring Roo是在Java平臺上提供快速應用程序開發的工具。 我已經解釋了何時使用它: http : //www.kai-waehner.de/blog/2011/04/05/when-to-use-spring-roo 。 Spring Roo目前支持兩種針對云計算的解決方案:Google App Engine(GAE)…

java程序日期轉換_Java 日期轉換詳解及實例代碼

Java 日期轉換涉及的核心類:Date類、SimpleDateFormat類、Calendar類一、 Date型與long型Date型轉換為long型Date date new Date();//取得當前時間Date類型long date2long date.getTime();//Date轉longlong型轉換為Date型long cur System.currentTimeMills();//取…

軟件設計之思想

編程用何種語言不重要,重要的是其設計思想。轉載于:https://www.cnblogs.com/redfull/p/6554898.html

asp.net 與 java 2017_[ASP.net教程]C#與JAVA學習感悟

[ASP.net教程]C#與JAVA學習感悟0 2015-10-06 23:00:07C#與JAVA學習感悟學完C#與JAVA,感覺收獲良多。C#與JAVA這兩門語言相似度很高(了解它們早期歷史的人可能知道為什么),也許很多人在學習JAVA(或C#)時會同時學習C#(或JAVA),因為它們太相似了…

Spring和JSF集成:國際化和本地化

如果您正在開發針對多種語言的JSF應用程序&#xff0c;那么您可能很熟悉<f&#xff1a;loadBundle>標記。 即使您的應用程序不支持使用消息包的國際化仍然是一個好主意。 在<f&#xff1a;loadBundle>標記下&#xff0c;它從Java java.util.ResourceBundle中讀取消…

一個實用的卻被忽略的命名空間:Microsoft.VisualBasic:

當你看到這個命名空間的時候&#xff0c;別因為是vb的東西就匆忙關掉網頁&#xff0c;那將會是您的損失&#xff0c;此命名空間中的資源最初目的是為了簡化vb.net開發而創建的&#xff0c;所以microsoft.visualbasic并不屬于system命名空間&#xff0c;而是獨立存在的。雖然是為…

Linux基礎之命令練習Day2-useradd(mod,del),groupadd(mod,del),chmod,chown,

作業一&#xff1a; 1) 新建用戶natasha&#xff0c;uid為1000&#xff0c;gid為555&#xff0c;備注信息為“master” 2) 修改natasha用戶的家目錄為/Natasha 3) 查看用戶信息配置文件的最后一行 4) 為natasha用戶設置密碼“123” 5) 查看用戶密碼配置文件的最后一行 6) 將nat…