SoFunction
Updated on 2024-11-17

VTK and Python to achieve robotic arm 3D model visualization details

The establishment of 3D visualization system relies on 3D graphics platforms, such as OpenGL, VTK, OGRE, OSG, etc. The traditional method mostly adopts OpenGL for the underlying programming, i.e., quantitative operation of its unique functions, which requires developers to be familiar with the relevant functions, thus causing problems such as development difficulty and long cycle time, etc. Platforms such as VTK, ORGE, OSG, etc., use better encapsulated functions to simplify the development process. Platforms such as VTK, ORGE, OSG, etc. simplify the development process by using better encapsulated functions. In the following, we will use Python and VTK to develop a rapid prototype of the robot's host computer monitoring interface.

A complete host computer program requires a 3D display module, a robot information monitoring module (position/angle/speed/power/temperature/error messages...) , communication module (serial port/USB/WIFI/Bluetooth...) , control module and other functional modules. The 3D display module is mainly used to display the robot's attitude (or position) information in real time. For example, if the robot's upper arm is raised, the virtual robot in the program interface will perform the same action at the same time. The 3D display module can also be used to control the robot and realize good human-machine interaction. For example, in the 3D image interface, you can click and pick up a joint of the robot, and drag and drop a part (limb) to control the real robot to perform the same movement. the graphical programming software Choregraphe from Aldebaran Robotics can perform some of the above functions to control the NAO robot.

For simple models you can write your own functions to create them, but the models made in this way are too simple and not realistic enough. Therefore, you can first create a good model in SolidWorks, Blender, 3DMax, Maya, Rhino and other three-dimensional design software, and then exported to a common three-dimensional file format, and then use VTK to read it in and rendering.

Design the large arm (upperarm) and small arm (forearm) of the robot in a 3D design software such as SolidWorks and then create the assembly as shown below. There are a few points to note before exporting the assembly as an STL file:

1. When an STL-type model is read in from the outside, it is displayed according to its internal coordinate position, so its position and size are determined. In order to position the model later and to make it easier to move, rotate, etc., it is necessary to create a coordinate system in SolidWorks first. As shown in the figure below, the coordinate system is established at the center point of the big arm joint.

2. If the assembly is exported as a whole as an STL file, it is not possible to control the relative movement of the parts after importing into VTK. Therefore, it is necessary to export each movable part of the assembly separately.

In the Save as STL dialog box of SolidWorks, click the Export tab, as shown in the following figure. Pay attention to the points mentioned before: if you check "Save all parts of the assembly in a single file", the whole assembly will be exported as one STL file, otherwise it will be two STL files named separately; in the Output coordinate system drop-down list, select the coordinate system 1 you created before, and check "Do not convert STL output data to positive coordinate space". "Do not convert STL output data to positive coordinate space".

The following Python code simply implements a 3D simulation of a 2-degree-of-freedom robotic arm, which can be controlled by dragging a slider or pressing the arrow keys on the keyboard to control the movement of the shoulder or elbow joints. Of course the program still has some problems to be improved...

#!/usr/bin/env python
 import vtk
import math
from  import *
filenames = ["",""]
dt = 1.0    # degree step in rotation
angle = [0, 0] # shoulder and elbow joint angle
renWin = ()
assembly = ()
slider_shoulder = vtk.vtkSliderRepresentation2D()
slider_elbow = vtk.vtkSliderRepresentation2D()
actor = list() # the list of links
# Customize vtkInteractorStyleTrackballCamera 
class MyInteractor():
  def __init__(self,parent=None):
    ("CharEvent",)
    ("KeyPressEvent",)
  # 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 = ().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"):
      (-dt)
      angle[0] += dt
      if angle[0] >= 360.0:
        angle[0] -= 360.0
      slider_shoulder.SetValue(angle[0])  
    if(key == "Down"):
      (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
    ()
    return
def LoadSTL(filename):
  reader = ()
  (filename)
  mapper = () # maps polygonal data to graphics primitives
  (())
  actor = () 
  (mapper)
  return actor  # represents an entity in a rendered scene
def CreateCoordinates():
  # create coordinate axes in the render window
  axes = () 
  (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. 
  (0) 
  (0.02) 
  axes.GetXAxisCaptionActor2D().SetWidth(0.03) 
  axes.GetYAxisCaptionActor2D().SetWidth(0.03) 
  axes.GetZAxisCaptionActor2D().SetWidth(0.03) 
  #(0) # Enable:1/disable:0 drawing the axis labels
  #transform = () 
  #(0.0, 0.0, 0.0)
  #(transform)
  #axes.GetXAxisCaptionActor2D().GetCaptionTextProperty().SetColor(1,0,0)
  #axes.GetXAxisCaptionActor2D().GetCaptionTextProperty().BoldOff() # disable text bolding
  return axes
def ShoulderSliderCallback(obj,event):
  sliderRepres = ()
  pos = () 
  (0,-pos,0)

  ()
def ElbowSliderCallback(obj,event):
  sliderRepres = ()
  pos = () 
  actor[1].SetOrientation(0,-pos,0)
  ()
def ConfigSlider(sliderRep, TitleText, Yaxes):
  (0.0)
  (360.0)
  (0.0) # Specify the current value for the widget
  (TitleText) # Specify the label text for this widget
  ().SetColor(1,0,0) # Change the color of the knob that slides
  ().SetColor(0,0,1) # Change the color of the knob when the mouse is held on it
  ().SetColor(1,1,0) # Change the color of the bar 
  ().SetColor(0,1,1) # Change the color of the ends of the bar
  #().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) 
  (0.02) # Specify the length of the slider  slider length by default is 0.05
  (0.02) # Set the width of the slider in the directions orthogonal to the slider axis
  (0.005)
  (0.03)

  () # display the slider text label
  ("%.1f")

  sliderWidget = ()
  (sliderRep)
  ()

  return sliderWidget
def CreateGround():
  # create plane source
  plane = ()
  (50)
  (50)
  (0,0,0)
  (0,0,1)  
  # mapper
  mapper = ()
  (())
   
  # actor
  actor = ()
  (mapper)
  ().SetRepresentationToWireframe()
  #().SetOpacity(0.4) # 1.0 is totally opaque and 0.0 is completely transparent
  ().SetColor(light_grey)
  '''
  # Load in the texture map. A texture is any unsigned char image.
  bmpReader = () 
  ("ground_texture.bmp") 
  texture = () 
  (()) 
  () 
  (texture)
  '''
  transform = ()
  (2000,2000, 1)
  (transform)
  return actor  
def CreateScene():
  # Create a rendering window and renderer
  ren = ()
  #renWin = ()
  (ren)
  # Create a renderwindowinteractor
  iren = ()
  (renWin)
  style = MyInteractor()
  (ren)
  (style)
  for id, file in enumerate(filenames):
    (LoadSTL(file))
    #actor[id].GetProperty().SetColor(blue)
    r = (.4, 1.0)
    g = (.4, 1.0)
    b = (.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)
    (actor[id])
    # Add the actors to the scene
    #(actor[id])
  # Also set the origin, position and orientation of assembly in space.
  (0, 0, 0) # This is the point about which all rotations take place 
  #(0, 0, 0)
  #(45)
  actor[1].SetOrigin(274, 0, 0) # initial elbow joint position
  (assembly)
  # Add coordinates
  axes = CreateCoordinates()
  (axes)

  # Add ground
  ground = CreateGround()
  (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
  (.2, .2, .2)

  # Set window size
  (600, 600)

  # Set up the camera to get a particular view of the scene
  camera = ()
  (300, 0, 0)
  (300, -400, 350)
  ()
  (0, 1, 0)
  (0.4)
  (camera)
  # Enable user interface interactor
  ()
  ()
if __name__ == "__main__":
  CreateScene()

The following is the use of MFC to build the robot host computer monitoring platform, you can realize some of the basic functions mentioned above. This GIF animation using open source software ScreenToGif generation, very good!

summarize

The above is the full content of this article on VTK and Python to achieve the three-dimensional model of the robotic arm visualization details, I hope it will help you. Interested friends can continue to refer to this site:

Code example of python+pygame simple drawing board implementation

Python implementation of a simple speech recognition system

Python built-in module turtle drawing details

If there are deficiencies, welcome to leave a message to point out. Thank you friends for the support of this site!