zoukankan      html  css  js  c++  java
  • VTK中的装配体(vtkAssembly)

      Actors有时也会组合在一起形成层次结构,当其中的某个Actor运动时,会影响到其他Actor的位置。例如,一个机械手臂可能由上臂、前臂、手腕和末端等部分通过关节连接起来。当上臂绕着肩关节旋转时,我们希望的是其他部分也会跟着运动。这种行为的实现就要用到Assembly,vtkAssembly是vtkActor的子类,它在构建机器人模型里非常有用。对串联机器人或串并联机器人来说,机构中存在着许多运动链,当前连杆的位置与姿态与它的父节点有关,父节点转动一定的角度,子节点也必须转动,否则模型就会断开。

      可以类比VREP中的三连杆机构,左侧的层次结构图中可以看到这样一条父子关系链:J1→L1→J2→L2→J3→L3。即基座关节J1可以看成运动链的根节点,转动J1剩下的两根连杆L2和L3也会同样旋转。

      下面我们在Python中实现用键盘控制三连杆机构的运动。首先在SolidWorks中绘制一个长度为100mm的连杆,然后创建装配体,依次将3个连杆首尾相连。按照之前的方法将装配体导出为3个STL模型文件。使用VTK的vtkSTLReader类读入STL文件,并编写事件处理的类处理键盘事件:

    #!/usr/bin/env python
    import vtk
    import math
    from vtk.util.colors import *
     
    filenames = ["link-1.stl","link-2.stl","link-3.stl"]
    dt = 1.0        # degree step in rotation
    renWin = vtk.vtkRenderWindow()
    actor  = list() # the list of links
    joint1 = vtk.vtkAssembly()  
    joint2 = vtk.vtkAssembly()
    joint3 = vtk.vtkAssembly()
    
    # 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):
            pass
        
        def OnKeyPressEvent(self,obj,event):
            global angle
            # Get the compound key strokes for the event
            key = self.GetInteractor().GetKeySym()
    # Handle an arrow key if(key == "Left"): joint1.RotateY(-dt) if(key == "Right"): joint1.RotateY(dt) if(key == "Up"): joint2.RotateY(-dt) if(key == "Down"): joint2.RotateY(dt) if(key == "a"): joint3.RotateY(-dt) if(key == "d"): joint3.RotateY(dt) # 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() mapper.SetInputConnection(reader.GetOutputPort()) actor = vtk.vtkLODActor() actor.SetMapper(mapper) return actor def CreateScene(): # Create a rendering window and renderer ren = vtk.vtkRenderer() 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)) 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]) joint2.SetOrigin(100, 0, 0) # initial elbow joint position joint3.SetOrigin(200, 0, 0) # initial wrist joint position ren.AddActor(joint1)
      # Set background color ren.GradientBackgroundOn() ren.SetBackground(.1, .1, .1) ren.SetBackground2(0.8,0.8,0.8) # Set window size renWin.SetSize(600, 600) # Enable user interface interactor iren.Initialize() iren.Start() if __name__ == "__main__": CreateScene()

      运行结果如下图所示。按键盘上的← →键可以控制连杆1,按↑ ↓键可以控制连杆2,按a、d键可以控制连杆3。在添加装配体后能保证旋转单个关节时其后面的子装配体也能跟着一起旋转。

    参考:

    如何制作一个可控制的人体骨骼模型

    VTK/Examples/Cxx/Interaction/Assembly

    http://vtk.1045678.n5.nabble.com/vtkassembly-td2804665.html

  • 相关阅读:
    PYTHON 函数总结
    PYTHON 模块总结
    python例题21--30
    python例题11--20
    python例题 1--10
    如何选中表格内同类名的某一行?
    table表格td内内容自动换行
    layer弹出层传值到父页面
    DIV内数据删除操作
    锚记搞定窗口滚动
  • 原文地址:https://www.cnblogs.com/21207-iHome/p/6534929.html
Copyright © 2011-2022 走看看