Importing a robot arm multibody model from a URDF file

Importing a robot arm multibody model from a URDF file#

The purpose of this notebook is to

  • demonstrate the creation of a Karana.Dynamics.Multibody instance for a robot arm from a URDF model file

  • show the structure of the loaded model

  • show a 3D visualization of the robot arm

  • serve as a hello world script for verifying a proper kdFlex installation

Resources

Acknowledgements The Barrett WAM urdf is sourced from the public repository barrett-ros2-pkg. Thank you to the authors and contributors.

Import kdFlex Python modules objects for use later

from pathlib import Path
import atexit
from Karana.Core import discard
from Karana.Frame import FrameContainer
from Karana.Dynamics.SOADyn_types import MultibodyDS

Build the filepath to the URDF file we will import

resources = Path().absolute().parent / "resources"
urdf_file = resources / "wam7dof" / "wam7dof_hand.urdf"

Import the URDF file to create a SOADyn_types.MultibodyDS. The “DS” is short for “Data Structure”. This is kdFlex’s native, file-format agnostic way of specifying a multibody. We’ll use this later on to instantiate the multibody.

multibody_info = MultibodyDS.fromUrdf(urdf_file)

Create a Karana.Frame.FrameContainer to manager the frames layer.

frame_container = FrameContainer("root")

Instantiate and configure the Karana.Dynamics.Multibody based on the MultibodyDS description.

multibody = multibody_info.toMultibody(frame_container)

Finalize the model to get it ready for use.

multibody.ensureCurrent()
multibody.resetData()

Set up the 3D graphics.

cleanup_viz, graphics = multibody.setupGraphics(port=0)
graphics.defaultCamera().pointCameraAt(
    offset=[0.2, 0.5, 1.7],
    target=[0, 0, 1],
    up=[1, 0, 0],
)
del graphics
[WebUI] Listening at http://newton:46263

Display the bodies in the multibody model.

multibody.displayModel()
      Body           Parent              Hinge   Dofs          
      ____           ______              _____   ____          
   1. FirstLink      wam7dof_MBVROOT_     PIN    1             
   2. SecondLink     FirstLink            PIN    1             
   3. ThirdLink      SecondLink           PIN    1             
   4. FourthLink     ThirdLink            PIN    1             
   5. FifthLink      FourthLink           PIN    1             
   6. SixthLink      FifthLink            PIN    1             
   7. SeventhLink    SixthLink            PIN    1             
   8. bhand_base     SeventhLink         LOCKED  0             
   9. bhand_link11   bhand_base           PIN    1             
  10. bhand_link12   bhand_link11         PIN    1             
  11. bhand_link13   bhand_link12         PIN    1             
  12. bhand_link21   bhand_base           PIN    1             
  13. bhand_link22   bhand_link21         PIN    1             
  14. bhand_link23   bhand_link22         PIN    1             
  15. bhand_link32   bhand_base           PIN    1             
  16. bhand_link33   bhand_link32         PIN    1             
                                                 ____          
                                                 15            

 Nodes
 ---

Display the topological structure of the multibody system

multibody.dumpTree()
|-wam7dof_MBVROOT_
   |-FirstLink
      |-SecondLink
         |-ThirdLink
            |-FourthLink
               |-FifthLink
                  |-SixthLink
                     |-SeventhLink
                        |-bhand_base
                           |-bhand_link11
                              |-bhand_link12
                                 |-bhand_link13
                           |-bhand_link21
                              |-bhand_link22
                                 |-bhand_link23
                           |-bhand_link32
                              |-bhand_link33

Animate the graphics by articulating the individual joints.

multibody.articulateBodies()

Cleanup

def cleanup():
    """Cleanup the simulation."""
    global multibody_info
    del multibody_info

    cleanup_viz()

    discard(multibody)
    discard(frame_container)


atexit.register(cleanup)
<function __main__.cleanup()>