Source code for brom_drake.example_helpers.block_handler_system

from importlib import resources as impresources

from pydrake.math import RollPitchYaw, RigidTransform, RotationMatrix
from pydrake.multibody.math import SpatialVelocity
from pydrake.multibody.parsing import Parser
from pydrake.multibody.plant import MultibodyPlant, CoulombFriction
from pydrake.systems.framework import (
    Diagram,
    DiagramBuilder,
    LeafSystem,
    PortDataType,
    BasicVector,
)

import numpy as np

# Internal Imports
from brom_drake import example_helpers as eh
from brom_drake.utils import AddGround, AddMultibodyTriad


[docs] class BlockHandlerSystem(LeafSystem): def __init__( self, plant: MultibodyPlant, scene_graph, block_name: str = "block_with_slots", model_urdf_path: str = None, ): LeafSystem.__init__(self) # Input Processing if model_urdf_path is None: model_urdf_path = str( impresources.files(eh) / "models/slider-block.urdf", ) # Constants self.block_name = block_name # Add the Block to the given plant self.plant = plant self.block_model_idx = Parser(plant=self.plant).AddModels(model_urdf_path)[0] self.block_model_name = self.plant.GetModelInstanceName(self.block_model_idx) self.block_body_name = "block" AddGround(self.plant) # Add ground to plant # Add the Triad self.scene_graph = scene_graph AddMultibodyTriad(plant.GetFrameByName(self.block_body_name), self.scene_graph) self.plant.Finalize() self.context = self.plant.CreateDefaultContext() # Create Input Port for the Slider Block System self.desired_pose_port = self.DeclareVectorInputPort( "desired_pose", BasicVector(6), ) # Create Output Port which should share the pose of the block self.DeclareVectorOutputPort( "measured_block_pose", BasicVector(6), self.SetBlockPose, {self.time_ticket()}, # indicate that this doesn't depend on any inputs, ) # but should still be updated each timestep
[docs] def SetBlockPose(self, context, output): """ Description: This function sets the desired pose of the block. """ # Get Desired Pose from Port plant_context = self.context pose_as_vec = self.desired_pose_port.Eval(context) self.plant.SetFreeBodyPose( plant_context, self.plant.GetBodyByName(self.block_body_name), RigidTransform(RollPitchYaw(pose_as_vec[:3]), pose_as_vec[3:]), ) # self.plant.SetFreeBodySpatialVelocity( # self.plant.GetBodyByName(self.block_body_name), # SpatialVelocity(np.zeros(3),np.array([0.0,0.0,0.0])), # plant_context # ) X_WBlock = self.plant.GetFreeBodyPose( plant_context, self.plant.GetBodyByName(self.block_body_name) ) pose_as_vector = np.hstack( [RollPitchYaw(X_WBlock.rotation()).vector(), X_WBlock.translation()] ) # Create Output output.SetFromVector(pose_as_vector)
[docs] def SetInitialBlockState(self, diagram_context): """ Description: Sets the initial position to be slightly above the ground (small, positive z value) to be . """ # Set Pose p_WBlock = [0.0, 0.0, 0.2] R_WBlock = RotationMatrix.MakeXRotation( np.pi / 2.0 ) # RotationMatrix.MakeXRotation(-np.pi/2.0) X_WBlock = RigidTransform(R_WBlock, p_WBlock) self.plant.SetFreeBodyPose( self.plant.GetMyContextFromRoot(diagram_context), self.plant.GetBodyByName(self.block_body_name), X_WBlock, ) # Set Velocities self.plant.SetFreeBodySpatialVelocity( self.plant.GetBodyByName(self.block_body_name), SpatialVelocity(np.zeros(3), np.array([0.0, 0.0, 0.0])), self.plant.GetMyContextFromRoot(diagram_context), )