日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > python >内容正文

python

python机械臂仿真_VTK与Python实现机械臂三维模型可视化详解

發(fā)布時(shí)間:2025/10/17 python 15 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python机械臂仿真_VTK与Python实现机械臂三维模型可视化详解 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

三維可視化系統(tǒng)的建立依賴于三維圖形平臺(tái), 如 OpenGL、VTK、OGRE、OSG等, 傳統(tǒng)的方法多采用OpenGL進(jìn)行底層編程,即對(duì)其特有的函數(shù)進(jìn)行定量操作, 需要開發(fā)人員熟悉相關(guān)函數(shù), 從而造成了開發(fā)難度大、 周期長(zhǎng)等問(wèn)題。VTK、 ORGE、OSG等平臺(tái)使用封裝更好的函數(shù)簡(jiǎn)化了開發(fā)過(guò)程。下面將使用Python與VTK進(jìn)行機(jī)器人上位機(jī)監(jiān)控界面的快速原型開發(fā)。

完整的上位機(jī)程序需要有三維顯示模塊、機(jī)器人信息監(jiān)測(cè)模塊(位置/角度/速度/電量/溫度/錯(cuò)誤信息...)、通信模塊(串口/USB/WIFI/藍(lán)牙...)、控制模塊等功能模塊。三維顯示模塊主要用于實(shí)時(shí)顯示機(jī)器人的姿態(tài)(或位置)信息。比如機(jī)器人上肢手臂抬起,程序界面中的虛擬機(jī)器人也會(huì)同時(shí)進(jìn)行同樣的動(dòng)作。三維顯示模塊也可以用于對(duì)機(jī)器人進(jìn)行控制,實(shí)現(xiàn)良好的人機(jī)交互。比如在三維圖像界面中可以點(diǎn)擊拾取機(jī)器人某一關(guān)節(jié),拖拽部件(肢體)控制真實(shí)的機(jī)器人完成同樣的運(yùn)動(dòng)。Aldebaran Robotics的圖形化編程軟件Choregraphe可以完成上述的一些功能對(duì)NAO機(jī)器人進(jìn)行控制。

對(duì)于簡(jiǎn)單的模型可以自己編寫函數(shù)進(jìn)行創(chuàng)建,但這種方法做出來(lái)的模型過(guò)于簡(jiǎn)單不夠逼真。因此可以先在SolidWorks、Blender、3DMax、Maya、Rhino等三維設(shè)計(jì)軟件中建立好模型,然后導(dǎo)出為通用的三維文件格式,再使用VTK將其讀入并進(jìn)行渲染。

在SolidWorks等三維設(shè)計(jì)軟件中設(shè)計(jì)好機(jī)器人的大臂(upperarm)和小臂(forearm),然后創(chuàng)建裝配體如下圖所示。在將裝配體導(dǎo)出為STL文件前需要注意幾點(diǎn):

1. 當(dāng)從外界讀入STL類型的模型時(shí),其會(huì)按照它內(nèi)部的坐標(biāo)位置進(jìn)行顯示,因此它的位置和大小是確定的。為了以后的定位以及移動(dòng)、旋轉(zhuǎn)等操作的方便,需要先在SolidWorks中創(chuàng)建一個(gè)坐標(biāo)系。如下圖所示,坐標(biāo)系建立在大臂關(guān)節(jié)中心點(diǎn)。

2. 如果將裝配體整體輸出為一個(gè)STL文件,則導(dǎo)入VTK后無(wú)法控制零部件進(jìn)行相對(duì)運(yùn)動(dòng)。因此,需要將裝配體各可動(dòng)部件分別導(dǎo)出。

在SolidWorks的另存為STL對(duì)話框中,點(diǎn)開輸出選項(xiàng)卡,如下圖所示。注意之前提到的幾點(diǎn):如果勾選“在單一文件中保存裝配體的所有零部件”則會(huì)將整個(gè)裝配體導(dǎo)出為一個(gè)STL文件,否則就是分別命名的兩個(gè)STL文件;輸出坐標(biāo)系下拉列表中選擇之前創(chuàng)建的坐標(biāo)系1,并勾選“不要轉(zhuǎn)換STL輸出數(shù)據(jù)到正的坐標(biāo)空間”。

下面的Python代碼簡(jiǎn)單實(shí)現(xiàn)了一個(gè)2自由度機(jī)械臂的三維仿真,可以拖動(dòng)滑塊或按鍵盤上的方向鍵控制肩關(guān)節(jié)或肘關(guān)節(jié)運(yùn)動(dòng)。當(dāng)然程序還存在一些問(wèn)題有待完善...

#!/usr/bin/env python

import vtk

import math

from vtk.util.colors import *

filenames = ["upperarm.stl","forearm.stl"]

dt = 1.0 # degree step in rotation

angle = [0, 0] # shoulder and elbow joint angle

renWin = vtk.vtkRenderWindow()

assembly = vtk.vtkAssembly()

slider_shoulder = vtk.vtkSliderRepresentation2D()

slider_elbow = vtk.vtkSliderRepresentation2D()

actor = list() # the list of links

# Customize vtkInteractorStyleTrackballCamera

class MyInteractor(vtk.vtkInteractorStyleTrackballCamera):

def __init__(self,parent=None):

self.AddObserver("CharEvent",self.OnCharEvent)

self.AddObserver("KeyPressEvent",self.OnKeyPressEvent)

# Override the default key operations which currently handle trackball or joystick styles is provided

# OnChar is triggered when an ASCII key is pressed. Some basic key presses are handled here

def OnCharEvent(self,obj,event):

pass

def OnKeyPressEvent(self,obj,event):

global angle

# Get the compound key strokes for the event

key = self.GetInteractor().GetKeySym()

# Output the key that was pressed

#print "Pressed: " , key

# Handle an arrow key

if(key == "Left"):

actor[1].RotateY(-dt)

if(key == "Right"):

actor[1].RotateY(dt)

if(key == "Up"):

assembly.RotateY(-dt)

angle[0] += dt

if angle[0] >= 360.0:

angle[0] -= 360.0

slider_shoulder.SetValue(angle[0])

if(key == "Down"):

assembly.RotateY(dt)

angle[0] -= dt

if angle[0] < 0.0:

angle[0] += 360.0

slider_shoulder.SetValue(angle[0])

# Ask each renderer owned by this RenderWindow to render its image and synchronize this process

renWin.Render()

return

def 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 scene

def CreateCoordinates():

# create coordinate axes in the render window

axes = vtk.vtkAxesActor()

axes.SetTotalLength(100, 100, 100) # 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)

axes.SetCylinderRadius(0.02)

axes.GetXAxisCaptionActor2D().SetWidth(0.03)

axes.GetYAxisCaptionActor2D().SetWidth(0.03)

axes.GetZAxisCaptionActor2D().SetWidth(0.03)

#axes.SetAxisLabels(0) # Enable:1/disable:0 drawing the axis labels

#transform = vtk.vtkTransform()

#transform.Translate(0.0, 0.0, 0.0)

#axes.SetUserTransform(transform)

#axes.GetXAxisCaptionActor2D().GetCaptionTextProperty().SetColor(1,0,0)

#axes.GetXAxisCaptionActor2D().GetCaptionTextProperty().BoldOff() # disable text bolding

return axes

def ShoulderSliderCallback(obj,event):

sliderRepres = obj.GetRepresentation()

pos = sliderRepres.GetValue()

assembly.SetOrientation(0,-pos,0)

renWin.Render()

def ElbowSliderCallback(obj,event):

sliderRepres = obj.GetRepresentation()

pos = sliderRepres.GetValue()

actor[1].SetOrientation(0,-pos,0)

renWin.Render()

def ConfigSlider(sliderRep, TitleText, Yaxes):

sliderRep.SetMinimumValue(0.0)

sliderRep.SetMaximumValue(360.0)

sliderRep.SetValue(0.0) # Specify the current value for the widget

sliderRep.SetTitleText(TitleText) # Specify the label text for this widget

sliderRep.GetSliderProperty().SetColor(1,0,0) # Change the color of the knob that slides

sliderRep.GetSelectedProperty().SetColor(0,0,1) # Change the color of the knob when the mouse is held on it

sliderRep.GetTubeProperty().SetColor(1,1,0) # Change the color of the bar

sliderRep.GetCapProperty().SetColor(0,1,1) # Change the color of the ends of the bar

#sliderRep.GetTitleProperty().SetColor(1,0,0) # Change the color of the text displaying the value

# Position the first end point of the slider

sliderRep.GetPoint1Coordinate().SetCoordinateSystemToDisplay()

sliderRep.GetPoint1Coordinate().SetValue(50, Yaxes)

# Position the second end point of the slider

sliderRep.GetPoint2Coordinate().SetCoordinateSystemToDisplay()

sliderRep.GetPoint2Coordinate().SetValue(400, Yaxes)

sliderRep.SetSliderLength(0.02) # Specify the length of the slider shape.The slider length by default is 0.05

sliderRep.SetSliderWidth(0.02) # Set the width of the slider in the directions orthogonal to the slider axis

sliderRep.SetTubeWidth(0.005)

sliderRep.SetEndCapWidth(0.03)

sliderRep.ShowSliderLabelOn() # display the slider text label

sliderRep.SetLabelFormat("%.1f")

sliderWidget = vtk.vtkSliderWidget()

sliderWidget.SetRepresentation(sliderRep)

sliderWidget.SetAnimationModeToAnimate()

return sliderWidget

def CreateGround():

# create plane source

plane = vtk.vtkPlaneSource()

plane.SetXResolution(50)

plane.SetYResolution(50)

plane.SetCenter(0,0,0)

plane.SetNormal(0,0,1)

# mapper

mapper = vtk.vtkPolyDataMapper()

mapper.SetInputConnection(plane.GetOutputPort())

# actor

actor = vtk.vtkActor()

actor.SetMapper(mapper)

actor.GetProperty().SetRepresentationToWireframe()

#actor.GetProperty().SetOpacity(0.4) # 1.0 is totally opaque and 0.0 is completely transparent

actor.GetProperty().SetColor(light_grey)

'''

# Load in the texture map. A texture is any unsigned char image.

bmpReader = vtk.vtkBMPReader()

bmpReader.SetFileName("ground_texture.bmp")

texture = vtk.vtkTexture()

texture.SetInputConnection(bmpReader.GetOutputPort())

texture.InterpolateOn()

actor.SetTexture(texture)

'''

transform = vtk.vtkTransform()

transform.Scale(2000,2000, 1)

actor.SetUserTransform(transform)

return actor

def CreateScene():

# Create a rendering window and renderer

ren = vtk.vtkRenderer()

#renWin = vtk.vtkRenderWindow()

renWin.AddRenderer(ren)

# Create a renderwindowinteractor

iren = vtk.vtkRenderWindowInteractor()

iren.SetRenderWindow(renWin)

style = MyInteractor()

style.SetDefaultRenderer(ren)

iren.SetInteractorStyle(style)

for id, file in enumerate(filenames):

actor.append(LoadSTL(file))

#actor[id].GetProperty().SetColor(blue)

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)

assembly.AddPart(actor[id])

# Add the actors to the scene

#ren.AddActor(actor[id])

# Also set the origin, position and orientation of assembly in space.

assembly.SetOrigin(0, 0, 0) # This is the point about which all rotations take place

#assembly.AddPosition(0, 0, 0)

#assembly.RotateX(45)

actor[1].SetOrigin(274, 0, 0) # initial elbow joint position

ren.AddActor(assembly)

# Add coordinates

axes = CreateCoordinates()

ren.AddActor(axes)

# Add ground

ground = CreateGround()

ren.AddActor(ground)

# Add slider to control the robot

sliderWidget_shoulder = ConfigSlider(slider_shoulder,"Shoulder Joint", 80)

sliderWidget_shoulder.SetInteractor(iren)

sliderWidget_shoulder.EnabledOn()

sliderWidget_shoulder.AddObserver("InteractionEvent", ShoulderSliderCallback)

sliderWidget_elbow = ConfigSlider(slider_elbow,"Elbow Joint", 160)

sliderWidget_elbow.SetInteractor(iren)

sliderWidget_elbow.EnabledOn()

sliderWidget_elbow.AddObserver("InteractionEvent", ElbowSliderCallback)

# Set background color

ren.SetBackground(.2, .2, .2)

# Set window size

renWin.SetSize(600, 600)

# Set up the camera to get a particular view of the scene

camera = vtk.vtkCamera()

camera.SetFocalPoint(300, 0, 0)

camera.SetPosition(300, -400, 350)

camera.ComputeViewPlaneNormal()

camera.SetViewUp(0, 1, 0)

camera.Zoom(0.4)

ren.SetActiveCamera(camera)

# Enable user interface interactor

iren.Initialize()

iren.Start()

if __name__ == "__main__":

CreateScene()

下面是使用MFC搭建的機(jī)器人上位機(jī)監(jiān)控平臺(tái),可以實(shí)現(xiàn)上述的一些基本功能。這個(gè)GIF動(dòng)畫使用開源軟件ScreenToGif生成,非常好用!

總結(jié)

以上就是本文關(guān)于VTK與Python實(shí)現(xiàn)機(jī)械臂三維模型可視化詳解的全部?jī)?nèi)容,希望對(duì)大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站:

如有不足之處,歡迎留言指出。感謝朋友們對(duì)本站的支持!

《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

總結(jié)

以上是生活随笔為你收集整理的python机械臂仿真_VTK与Python实现机械臂三维模型可视化详解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。