def do_exploding_iiwa_sim(self, plant_src, scene_graph_src, context_src): # Show a simulation which "changes state" by being rebuilt. builder = DiagramBuilder() plant, scene_graph = AddMultibodyPlantSceneGraph(builder, time_step=1e-3) subgraph_src = mut.MultibodyPlantSubgraph( mut.get_elements_from_plant(plant_src, scene_graph_src)) to_plant = subgraph_src.add_to(plant, scene_graph) # Add ground plane. X_FH = HalfSpace.MakePose([0, 0, 1], [0, 0, 0]) plant.RegisterCollisionGeometry(plant.world_body(), X_FH, HalfSpace(), "ground_plane_collision", CoulombFriction(0.8, 0.3)) plant.Finalize() # Loosey-goosey - no control. for model in me.get_model_instances(plant): util.no_control(builder, plant, model) if VISUALIZE: print("do_exploding_iiwa_sim") role = Role.kIllustration ConnectDrakeVisualizer(builder, scene_graph, role=role) ConnectContactResultsToDrakeVisualizer(builder, plant) diagram = builder.Build() # Set up context. d_context = diagram.CreateDefaultContext() context = plant.GetMyContextFromRoot(d_context) to_plant.copy_state(context_src, context) # - Hoist IIWA up in the air. plant.SetFreeBodyPose(context, plant.GetBodyByName("base"), RigidTransform([0, 0, 1.])) # - Set joint velocities to "spin" it in the air. for joint in me.get_joints(plant): if isinstance(joint, RevoluteJoint): me.set_joint_positions(plant, context, joint, 0.7) me.set_joint_velocities(plant, context, joint, -5.) def monitor(d_context): # Stop the simulation once there's any contact. context = plant.GetMyContextFromRoot(d_context) query_object = plant.get_geometry_query_input_port().Eval(context) if query_object.HasCollisions(): return EventStatus.ReachedTermination(plant, "Contact") else: return EventStatus.DidNothing() # Forward simulate. simulator = Simulator(diagram, d_context) simulator.Initialize() simulator.set_monitor(monitor) if VISUALIZE: simulator.set_target_realtime_rate(1.) simulator.AdvanceTo(2.) # Try to push a bit further. simulator.clear_monitor() simulator.AdvanceTo(d_context.get_time() + 0.05) diagram.Publish(d_context) # Recreate simulator. builder_new = DiagramBuilder() plant_new, scene_graph_new = AddMultibodyPlantSceneGraph( builder_new, time_step=plant.time_step()) subgraph = mut.MultibodyPlantSubgraph( mut.get_elements_from_plant(plant, scene_graph)) # Remove all joints; make them floating bodies. for joint in me.get_joints(plant): subgraph.remove_joint(joint) # Remove massless bodies. for body in me.get_bodies(plant): if body is plant.world_body(): continue if body.default_mass() == 0.: subgraph.remove_body(body) # Finalize. to_new = subgraph.add_to(plant_new, scene_graph_new) plant_new.Finalize() if VISUALIZE: ConnectDrakeVisualizer(builder_new, scene_graph_new, role=role) ConnectContactResultsToDrakeVisualizer(builder_new, plant_new) diagram_new = builder_new.Build() # Remap state. d_context_new = diagram_new.CreateDefaultContext() d_context_new.SetTime(d_context.get_time()) context_new = plant_new.GetMyContextFromRoot(d_context_new) to_new.copy_state(context, context_new) # Simulate. simulator_new = Simulator(diagram_new, d_context_new) simulator_new.Initialize() diagram_new.Publish(d_context_new) if VISUALIZE: simulator_new.set_target_realtime_rate(1.) simulator_new.AdvanceTo(context_new.get_time() + 2) if VISUALIZE: input(" Press enter...")
default=False) args = parser.parse_args() file_name = FindResourceOrThrow( "drake/examples/multibody/cart_pole/cart_pole.sdf") builder = DiagramBuilder() scene_graph = builder.AddSystem(SceneGraph()) cart_pole = builder.AddSystem(MultibodyPlant()) AddModelFromSdfFile(file_name=file_name, plant=cart_pole, scene_graph=scene_graph) cart_pole.AddForceElement(UniformGravityFieldElement([0, 0, -9.81])) cart_pole.Finalize(scene_graph) assert cart_pole.geometry_source_is_registered() builder.Connect(scene_graph.get_query_output_port(), cart_pole.get_geometry_query_input_port()) builder.Connect(cart_pole.get_geometry_poses_output_port(), scene_graph.get_source_pose_port(cart_pole.get_source_id())) builder.ExportInput(cart_pole.get_actuation_input_port()) ConnectDrakeVisualizer(builder=builder, scene_graph=scene_graph) diagram = builder.Build() diagram.set_name("graphviz_example") plot_system_graphviz(diagram, max_depth=2) if not args.test: plt.show()
def RunRealRobot(self, plan_list, gripper_setpoint_list, sim_duration=None, extra_time=2.0, is_plan_runner_diagram=False,): """ Constructs a Diagram that sends commands to ManipulationStationHardwareInterface. @param plan_list: A list of Plans to be executed. @param gripper_setpoint_list: A list of gripper setpoints. Each setpoint corresponds to a Plan. @param sim_duration: the duration of simulation in seconds. If unset, it is set to the sum of the durations of all plans in plan_list plus extra_time. @param extra_time: the amount of time for which commands are sent, in addition to the duration of all plans. @param is_plan_runner_diagram: True: use the diagram version of PlanRunner; False: use the leaf version of PlanRunner. @return: logs of robot configuration and torque, decoded from LCM messges sent by the robot's driver. Logs are SignalLogger systems, whose data can be accessed by SignalLogger.data(). """ builder = DiagramBuilder() camera_ids = ["805212060544"] station_hardware = ManipulationStationHardwareInterface(camera_ids) station_hardware.Connect(wait_for_cameras=False) builder.AddSystem(station_hardware) # Add plan runner. if is_plan_runner_diagram: plan_runner = CreateManipStationPlanRunnerDiagram( station=self.station, kuka_plans=plan_list, gripper_setpoint_list=gripper_setpoint_list, print_period=0,) else: plan_runner = ManipStationPlanRunner( station=self.station, kuka_plans=plan_list, gripper_setpoint_list=gripper_setpoint_list, print_period=0,) builder.AddSystem(plan_runner) builder.Connect(plan_runner.GetOutputPort("gripper_setpoint"), station_hardware.GetInputPort("wsg_position")) builder.Connect(plan_runner.GetOutputPort("force_limit"), station_hardware.GetInputPort("wsg_force_limit")) demux = builder.AddSystem(Demultiplexer(14, 7)) builder.Connect( plan_runner.GetOutputPort("iiwa_position_and_torque_command"), demux.get_input_port(0)) builder.Connect(demux.get_output_port(0), station_hardware.GetInputPort("iiwa_position")) builder.Connect(demux.get_output_port(1), station_hardware.GetInputPort("iiwa_feedforward_torque")) builder.Connect(station_hardware.GetOutputPort("iiwa_position_measured"), plan_runner.GetInputPort("iiwa_position")) builder.Connect(station_hardware.GetOutputPort("iiwa_velocity_estimated"), plan_runner.GetInputPort("iiwa_velocity")) # Add logger iiwa_position_command_log = LogOutput(demux.get_output_port(0), builder) iiwa_position_command_log._DeclarePeriodicPublish(0.005) iiwa_position_measured_log = LogOutput( station_hardware.GetOutputPort("iiwa_position_measured"), builder) iiwa_position_measured_log._DeclarePeriodicPublish(0.005) iiwa_external_torque_log = LogOutput( station_hardware.GetOutputPort("iiwa_torque_external"), builder) iiwa_external_torque_log._DeclarePeriodicPublish(0.005) # build diagram diagram = builder.Build() # RenderSystemWithGraphviz(diagram) # construct simulator simulator = Simulator(diagram) self.simulator = simulator simulator.set_target_realtime_rate(1.0) simulator.set_publish_every_time_step(False) t_plan = GetPlanStartingTimes(plan_list) if sim_duration is None: sim_duration = t_plan[-1] + extra_time print "sending trajectories in 2 seconds..." time.sleep(1.0) print "sending trajectories in 1 second..." time.sleep(1.0) print "sending trajectories now!" simulator.StepTo(sim_duration) return iiwa_position_command_log, \ iiwa_position_measured_log, iiwa_external_torque_log
def main(): args_parser = argparse.ArgumentParser( description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) add_filename_and_parser_argparse_arguments(args_parser) add_visualizers_argparse_arguments(args_parser) args_parser.add_argument( "--position", type=float, nargs="+", default=[], help="A list of positions which must be the same length as the number " "of positions in the sdf model. Note that most models have a " "floating-base joint by default (unless the sdf explicitly welds " "the base to the world, and so have 7 positions corresponding to " "the quaternion representation of that floating-base position.") # TODO(eric.cousineau): Support sliders (or widgets) for floating body # poses. # TODO(russt): Once floating body sliders are supported, add an option to # disable them too, either by welding via GetUniqueBaseBody #9747 or by # hiding the widgets. args_parser.add_argument( "--test", action='store_true', help="Disable opening the slider gui window for testing.") args = args_parser.parse_args() # NOTE: meshcat is required to create the JointSliders. args.meshcat = True filename, make_parser = parse_filename_and_parser(args_parser, args) update_visualization, connect_visualizers = parse_visualizers( args_parser, args) builder = DiagramBuilder() scene_graph = builder.AddSystem(SceneGraph()) # Construct a MultibodyPlant. # N.B. Do not use AddMultibodyPlantSceneGraph because we want to inject our # custom pose-bundle adjustments for the sliders. plant = MultibodyPlant(time_step=0.0) plant.RegisterAsSourceForSceneGraph(scene_graph) # Add the model from the file and finalize the plant. make_parser(plant).AddModelFromFile(filename) update_visualization(plant, scene_graph) plant.Finalize() meshcat = connect_visualizers(builder, plant, scene_graph, publish_contacts=False) assert meshcat is not None, "Meshcat visualizer not created but required." # Add sliders to set positions of the joints. sliders = builder.AddSystem(JointSliders(meshcat=meshcat, plant=plant)) to_pose = builder.AddSystem(MultibodyPositionToGeometryPose(plant)) builder.Connect(sliders.get_output_port(0), to_pose.get_input_port()) builder.Connect(to_pose.get_output_port(), scene_graph.get_source_pose_port(plant.get_source_id())) if len(args.position): sliders.SetPositions(args.position) # Make the diagram and run it. diagram = builder.Build() simulator = Simulator(diagram) if args.test: simulator.AdvanceTo(0.1) else: simulator.set_target_realtime_rate(1.0) simulator.AdvanceTo(np.inf)
def DepthCameraDemoSystem(): builder = DiagramBuilder() # If you have trouble finding resources, you can enable trace logging # to see how `FindResource*` is searching. set_log_level("trace") # Create the physics engine + scene graph. plant, scene_graph = AddMultibodyPlantSceneGraph(builder, time_step=0.0) # Add a single object into it. Parser(plant, scene_graph).AddModelFromFile(FindResourceOrThrow( "drake/manipulation/models/ycb/sdf/006_mustard_bottle.sdf")) # Add a rendering engine renderer = "my_renderer" scene_graph.AddRenderer(renderer, MakeRenderEngineVtk(RenderEngineVtkParams())) plant.Finalize() # Add a visualizer just to help us see the object. use_meshcat = False if use_meshcat: meshcat = builder.AddSystem(MeshcatVisualizer(scene_graph)) builder.Connect(scene_graph.get_pose_bundle_output_port(), meshcat.get_input_port(0)) # Add a camera to the environment. pose = RigidTransform(RollPitchYaw(-0.2, 0.2, 0), [-.1, -0.1, -.5]) properties = DepthCameraProperties( width=640, height=480, fov_y=np.pi / 4.0, renderer_name=renderer, z_near=0.1, z_far=10.0) camera = builder.AddSystem(RgbdSensor( parent_id=scene_graph.world_frame_id(), X_PB=pose, properties=properties, show_window=False)) camera.set_name("rgbd_sensor") builder.Connect(scene_graph.get_query_output_port(), camera.query_object_input_port()) # Export the camera outputs builder.ExportOutput(camera.color_image_output_port(), "color_image") builder.ExportOutput(camera.depth_image_32F_output_port(), "depth_image") # Add a system to convert the camera output into a point cloud to_point_cloud = builder.AddSystem( DepthImageToPointCloud( camera_info=camera.depth_camera_info(), fields=BaseField.kXYZs | BaseField.kRGBs)) builder.Connect( camera.depth_image_32F_output_port(), to_point_cloud.depth_image_input_port()) builder.Connect( camera.color_image_output_port(), to_point_cloud.color_image_input_port()) # Export the point cloud output. builder.ExportOutput( to_point_cloud.point_cloud_output_port(), "point_cloud") diagram = builder.Build() diagram.set_name("depth_camera_demo_system") return diagram
def main(): parser = argparse.ArgumentParser(description=__doc__) parser.add_argument( "--target_realtime_rate", type=float, default=1.0, help="Desired rate relative to real time. See documentation for " "Simulator::set_target_realtime_rate() for details.") parser.add_argument("--duration", type=float, default=np.inf, help="Desired duration of the simulation in seconds.") parser.add_argument( "--hardware", action='store_true', help="Use the ManipulationStationHardwareInterface instead of an " "in-process simulation.") parser.add_argument("--test", action='store_true', help="Disable opening the gui window for testing.") parser.add_argument( "--filter_time_const", type=float, default=0.1, help="Time constant for the first order low pass filter applied to" "the teleop commands") parser.add_argument( "--velocity_limit_factor", type=float, default=1.0, help="This value, typically between 0 and 1, further limits the " "iiwa14 joint velocities. It multiplies each of the seven " "pre-defined joint velocity limits. " "Note: The pre-defined velocity limits are specified by " "iiwa14_velocity_limits, found in this python file.") parser.add_argument( '--setup', type=str, default='manipulation_class', help="The manipulation station setup to simulate. ", choices=['manipulation_class', 'clutter_clearing', 'planar']) parser.add_argument( '--schunk_collision_model', type=str, default='box', help="The Schunk collision model to use for simulation. ", choices=['box', 'box_plus_fingertip_spheres']) parser.add_argument( "-w", "--open-window", dest="browser_new", action="store_const", const=1, default=None, help=( "Open the MeshCat display in a new browser window. NOTE: the " "slider controls are available in the meshcat viewer by clicking " "'Open Controls' in the top-right corner.")) args = parser.parse_args() builder = DiagramBuilder() # NOTE: the meshcat instance is always created in order to create the # teleop controls (orientation sliders and open/close gripper button). When # args.hardware is True, the meshcat server will *not* display robot # geometry, but it will contain the joint sliders and open/close gripper # button in the "Open Controls" tab in the top-right of the viewing server. meshcat = Meshcat() if args.hardware: station = builder.AddSystem(ManipulationStationHardwareInterface()) station.Connect(wait_for_cameras=False) else: station = builder.AddSystem(ManipulationStation()) if args.schunk_collision_model == "box": schunk_model = SchunkCollisionModel.kBox elif args.schunk_collision_model == "box_plus_fingertip_spheres": schunk_model = SchunkCollisionModel.kBoxPlusFingertipSpheres # Initializes the chosen station type. if args.setup == 'manipulation_class': station.SetupManipulationClassStation(schunk_model=schunk_model) station.AddManipulandFromFile( "drake/examples/manipulation_station/models/" + "061_foam_brick.sdf", RigidTransform(RotationMatrix.Identity(), [0.6, 0, 0])) elif args.setup == 'clutter_clearing': station.SetupClutterClearingStation(schunk_model=schunk_model) ycb_objects = CreateClutterClearingYcbObjectList() for model_file, X_WObject in ycb_objects: station.AddManipulandFromFile(model_file, X_WObject) elif args.setup == 'planar': station.SetupPlanarIiwaStation(schunk_model=schunk_model) station.AddManipulandFromFile( "drake/examples/manipulation_station/models/" + "061_foam_brick.sdf", RigidTransform(RotationMatrix.Identity(), [0.6, 0, 0])) station.Finalize() # If using meshcat, don't render the cameras, since RgbdCamera # rendering only works with drake-visualizer. Without this check, # running this code in a docker container produces libGL errors. geometry_query_port = station.GetOutputPort("geometry_query") # Connect the meshcat visualizer. meshcat_visualizer = MeshcatVisualizerCpp.AddToBuilder( builder=builder, query_object_port=geometry_query_port, meshcat=meshcat) # Configure the planar visualization. if args.setup == 'planar': meshcat.Set2dRenderMode() ConnectPlanarSceneGraphVisualizer(builder, station.get_scene_graph(), geometry_query_port) # Connect and publish to drake visualizer. DrakeVisualizer.AddToBuilder(builder, geometry_query_port) image_to_lcm_image_array = builder.AddSystem(ImageToLcmImageArrayT()) image_to_lcm_image_array.set_name("converter") for name in station.get_camera_names(): cam_port = (image_to_lcm_image_array.DeclareImageInputPort[ PixelType.kRgba8U]("camera_" + name)) builder.Connect( station.GetOutputPort("camera_" + name + "_rgb_image"), cam_port) image_array_lcm_publisher = builder.AddSystem( LcmPublisherSystem.Make(channel="DRAKE_RGBD_CAMERA_IMAGES", lcm_type=lcmt_image_array, lcm=None, publish_period=0.1, use_cpp_serializer=True)) image_array_lcm_publisher.set_name("rgbd_publisher") builder.Connect( image_to_lcm_image_array.image_array_t_msg_output_port(), image_array_lcm_publisher.get_input_port(0)) if args.browser_new is not None: url = meshcat.web_url() webbrowser.open(url=url, new=args.browser_new) robot = station.get_controller_plant() params = DifferentialInverseKinematicsParameters(robot.num_positions(), robot.num_velocities()) time_step = 0.005 params.set_timestep(time_step) # True velocity limits for the IIWA14 (in rad, rounded down to the first # decimal) iiwa14_velocity_limits = np.array([1.4, 1.4, 1.7, 1.3, 2.2, 2.3, 2.3]) if args.setup == 'planar': # Extract the 3 joints that are not welded in the planar version. iiwa14_velocity_limits = iiwa14_velocity_limits[1:6:2] # The below constant is in body frame. params.set_end_effector_velocity_gain([1, 0, 0, 0, 1, 1]) # Stay within a small fraction of those limits for this teleop demo. factor = args.velocity_limit_factor params.set_joint_velocity_limits( (-factor * iiwa14_velocity_limits, factor * iiwa14_velocity_limits)) differential_ik = builder.AddSystem( DifferentialIK(robot, robot.GetFrameByName("iiwa_link_7"), params, time_step)) builder.Connect(differential_ik.GetOutputPort("joint_position_desired"), station.GetInputPort("iiwa_position")) teleop = builder.AddSystem( EndEffectorTeleop(meshcat, args.setup == 'planar')) filter = builder.AddSystem( FirstOrderLowPassFilter(time_constant=args.filter_time_const, size=6)) builder.Connect(teleop.get_output_port(0), filter.get_input_port(0)) builder.Connect(filter.get_output_port(0), differential_ik.GetInputPort("rpy_xyz_desired")) wsg_buttons = builder.AddSystem(SchunkWsgButtons(meshcat=meshcat)) builder.Connect(wsg_buttons.GetOutputPort("position"), station.GetInputPort("wsg_position")) builder.Connect(wsg_buttons.GetOutputPort("force_limit"), station.GetInputPort("wsg_force_limit")) # When in regression test mode, log our joint velocities to later check # that they were sufficiently quiet. num_iiwa_joints = station.num_iiwa_joints() if args.test: iiwa_velocities = builder.AddSystem(VectorLogSink(num_iiwa_joints)) builder.Connect(station.GetOutputPort("iiwa_velocity_estimated"), iiwa_velocities.get_input_port(0)) else: iiwa_velocities = None diagram = builder.Build() simulator = Simulator(diagram) # This is important to avoid duplicate publishes to the hardware interface: simulator.set_publish_every_time_step(False) station_context = diagram.GetMutableSubsystemContext( station, simulator.get_mutable_context()) station.GetInputPort("iiwa_feedforward_torque").FixValue( station_context, np.zeros(num_iiwa_joints)) # If the diagram is only the hardware interface, then we must advance it a # little bit so that first LCM messages get processed. A simulated plant is # already publishing correct positions even without advancing, and indeed # we must not advance a simulated plant until the sliders and filters have # been initialized to match the plant. if args.hardware: simulator.AdvanceTo(1e-6) q0 = station.GetOutputPort("iiwa_position_measured").Eval(station_context) differential_ik.parameters.set_nominal_joint_position(q0) teleop.SetPose(differential_ik.ForwardKinematics(q0)) filter.set_initial_output_value( diagram.GetMutableSubsystemContext(filter, simulator.get_mutable_context()), teleop.get_output_port(0).Eval( diagram.GetMutableSubsystemContext( teleop, simulator.get_mutable_context()))) differential_ik.SetPositions( diagram.GetMutableSubsystemContext(differential_ik, simulator.get_mutable_context()), q0) simulator.set_target_realtime_rate(args.target_realtime_rate) simulator.AdvanceTo(args.duration) # Ensure that our initialization logic was correct, by inspecting our # logged joint velocities. if args.test: iiwa_velocities_log = iiwa_velocities.FindLog(simulator.get_context()) for time, qdot in zip(iiwa_velocities_log.sample_times(), iiwa_velocities_log.data().transpose()): # TODO(jwnimmer-tri) We should be able to do better than a 40 # rad/sec limit, but that's the best we can enforce for now. if qdot.max() > 0.1: print(f"ERROR: large qdot {qdot} at time {time}") sys.exit(1)
def main(): builder = DiagramBuilder() station = builder.AddSystem(ManipulationStation()) station.SetupClutterClearingStation() station.Finalize() package_map = PackageMap() package_map.PopulateFromEnvironment('AMENT_PREFIX_PATH') sdf_file_path = os.path.join(package_map.GetPath('iiwa14_description'), 'iiwa14_no_collision.sdf') joint_names = [ 'iiwa_joint_1', 'iiwa_joint_2', 'iiwa_joint_3', 'iiwa_joint_4', 'iiwa_joint_5', 'iiwa_joint_6', 'iiwa_joint_7' ] joints = [] for name in joint_names: joints.append(station.get_controller_plant().GetJointByName(name)) rclpy.init() node = rclpy.create_node('interactive_demo') # Publish SDF content on robot_description topic latching_qos = QoSProfile(depth=1, durability=DurabilityPolicy.TRANSIENT_LOCAL) description_publisher = node.create_publisher(StringMsg, 'robot_description', qos_profile=latching_qos) msg = StringMsg() with open(sdf_file_path, 'r') as sdf_file: msg.data = sdf_file.read() description_publisher.publish(msg) clock_system = SystemClock() builder.AddSystem(clock_system) # Transform broadcaster for TF frames tf_broadcaster = TransformBroadcaster(node) # Connect to system that publishes TF transforms tf_system = builder.AddSystem( TFPublisher(tf_broadcaster=tf_broadcaster, joints=joints)) tf_buffer = Buffer(node=node) tf_listener = TransformListener(tf_buffer, node) server = InteractiveMarkerServer(node, 'joint_targets') joint_target_system = builder.AddSystem( MovableJoints(server, tf_buffer, joints)) fk_system = builder.AddSystem( ForwardKinematics(station.get_controller_plant())) builder.Connect(station.GetOutputPort('iiwa_position_measured'), fk_system.GetInputPort('joint_positions')) builder.Connect(fk_system.GetOutputPort('transforms'), tf_system.GetInputPort('body_poses')) builder.Connect(clock_system.GetOutputPort('clock'), tf_system.GetInputPort('clock')) builder.Connect(joint_target_system.GetOutputPort('joint_states'), station.GetInputPort('iiwa_position')) ConnectDrakeVisualizer(builder, station.get_scene_graph(), station.GetOutputPort("pose_bundle")) constant_sys = builder.AddSystem(ConstantVectorSource(numpy.array([0.107 ]))) builder.Connect(constant_sys.get_output_port(0), station.GetInputPort("wsg_position")) diagram = builder.Build() simulator = Simulator(diagram) simulator_context = simulator.get_mutable_context() simulator.set_target_realtime_rate(1.0) station_context = station.GetMyMutableContextFromRoot(simulator_context) num_iiwa_joints = station.num_iiwa_joints() station.GetInputPort("iiwa_feedforward_torque").FixValue( station_context, numpy.zeros(num_iiwa_joints)) while simulator_context.get_time() < 12345: simulator.AdvanceTo(simulator_context.get_time() + 0.01) # TODO(sloretz) really need a spin_some in rclpy rclpy.spin_once(node, timeout_sec=0) rclpy.shutdown()
def main(): parser = argparse.ArgumentParser(description=__doc__) parser.add_argument( "--target_realtime_rate", type=float, default=1.0, help="Desired rate relative to real time. See documentation for " "Simulator::set_target_realtime_rate() for details.") parser.add_argument( "--duration", type=float, default=np.inf, help="Desired duration of the simulation in seconds.") parser.add_argument( "--hardware", action='store_true', help="Use the ManipulationStationHardwareInterface instead of an " "in-process simulation.") parser.add_argument( "--joystick_id", type=int, default=None, help="Joystick ID to use (0..N-1). If not specified, then only one " "joystick must be plugged in, and that joystick will be used.") parser.add_argument( "--test", action='store_true', help="Disable opening the gui window for testing.") parser.add_argument( "--time_step", type=float, default=0.005, help="Time constant for the differential IK solver and first order" "low pass filter applied to the teleop commands") parser.add_argument( "--velocity_limit_factor", type=float, default=1.0, help="This value, typically between 0 and 1, further limits the " "iiwa14 joint velocities. It multiplies each of the seven " "pre-defined joint velocity limits. " "Note: The pre-defined velocity limits are specified by " "iiwa14_velocity_limits, found in this python file.") parser.add_argument( '--setup', type=str, default='manipulation_class', help="The manipulation station setup to simulate. ", choices=['manipulation_class', 'clutter_clearing']) parser.add_argument( '--schunk_collision_model', type=str, default='box', help="The Schunk collision model to use for simulation. ", choices=['box', 'box_plus_fingertip_spheres']) parser.add_argument( "--meshcat", action="store_true", default=False, help="Enable visualization with meshcat.") parser.add_argument( "-w", "--open-window", dest="browser_new", action="store_const", const=1, default=None, help="Open the MeshCat display in a new browser window.") args = parser.parse_args() if (args.browser_new is not None) and (not args.meshcat): parser.error( "-w / --show-window is only valid in conjunction with --meshcat") if args.test: # Don't grab mouse focus during testing. # See: https://stackoverflow.com/a/52528832/7829525 os.environ["SDL_VIDEODRIVER"] = "dummy" builder = DiagramBuilder() if args.hardware: station = builder.AddSystem(ManipulationStationHardwareInterface()) station.Connect(wait_for_cameras=False) else: station = builder.AddSystem(ManipulationStation()) if args.schunk_collision_model == "box": schunk_model = SchunkCollisionModel.kBox elif args.schunk_collision_model == "box_plus_fingertip_spheres": schunk_model = SchunkCollisionModel.kBoxPlusFingertipSpheres # Initializes the chosen station type. if args.setup == 'manipulation_class': station.SetupManipulationClassStation( schunk_model=schunk_model) station.AddManipulandFromFile( ("drake/examples/manipulation_station/models/" "061_foam_brick.sdf"), RigidTransform(RotationMatrix.Identity(), [0.6, 0, 0])) elif args.setup == 'clutter_clearing': station.SetupClutterClearingStation( schunk_model=schunk_model) ycb_objects = CreateClutterClearingYcbObjectList() for model_file, X_WObject in ycb_objects: station.AddManipulandFromFile(model_file, X_WObject) station.Finalize() query_port = station.GetOutputPort("query_object") DrakeVisualizer.AddToBuilder(builder, query_port) if args.meshcat: meshcat = Meshcat() MeshcatVisualizerCpp.AddToBuilder( builder=builder, query_object_port=query_port, meshcat=meshcat) if args.setup == 'planar': meshcat.Set2dRenderMode() if args.browser_new is not None: url = meshcat.web_url() webbrowser.open(url=url, new=args.browser_new) robot = station.get_controller_plant() params = DifferentialInverseKinematicsParameters(robot.num_positions(), robot.num_velocities()) params.set_timestep(args.time_step) # True velocity limits for the IIWA14 (in rad/s, rounded down to the first # decimal) iiwa14_velocity_limits = np.array([1.4, 1.4, 1.7, 1.3, 2.2, 2.3, 2.3]) # Stay within a small fraction of those limits for this teleop demo. factor = args.velocity_limit_factor params.set_joint_velocity_limits((-factor*iiwa14_velocity_limits, factor*iiwa14_velocity_limits)) differential_ik = builder.AddSystem(DifferentialIK( robot, robot.GetFrameByName("iiwa_link_7"), params, args.time_step)) builder.Connect(differential_ik.GetOutputPort("joint_position_desired"), station.GetInputPort("iiwa_position")) joystick = initialize_joystick(args.joystick_id) teleop = builder.AddSystem(DualShock4Teleop(joystick)) filter_ = builder.AddSystem( FirstOrderLowPassFilter(time_constant=args.time_step, size=6)) builder.Connect(teleop.get_output_port(0), filter_.get_input_port(0)) builder.Connect(filter_.get_output_port(0), differential_ik.GetInputPort("rpy_xyz_desired")) builder.Connect(teleop.GetOutputPort("position"), station.GetInputPort( "wsg_position")) builder.Connect(teleop.GetOutputPort("force_limit"), station.GetInputPort("wsg_force_limit")) diagram = builder.Build() simulator = Simulator(diagram) # This is important to avoid duplicate publishes to the hardware interface: simulator.set_publish_every_time_step(False) station_context = diagram.GetMutableSubsystemContext( station, simulator.get_mutable_context()) station.GetInputPort("iiwa_feedforward_torque").FixValue( station_context, np.zeros(7)) # If the diagram is only the hardware interface, then we must advance it a # little bit so that first LCM messages get processed. A simulated plant is # already publishing correct positions even without advancing, and indeed # we must not advance a simulated plant until the sliders and filters have # been initialized to match the plant. if args.hardware: simulator.AdvanceTo(1e-6) q0 = station.GetOutputPort("iiwa_position_measured").Eval(station_context) differential_ik.parameters.set_nominal_joint_position(q0) teleop.SetPose(differential_ik.ForwardKinematics(q0)) filter_.set_initial_output_value( diagram.GetMutableSubsystemContext( filter_, simulator.get_mutable_context()), teleop.get_output_port(0).Eval(diagram.GetMutableSubsystemContext( teleop, simulator.get_mutable_context()))) differential_ik.SetPositions(diagram.GetMutableSubsystemContext( differential_ik, simulator.get_mutable_context()), q0) simulator.set_target_realtime_rate(args.target_realtime_rate) print_instructions() simulator.AdvanceTo(args.duration)
def main(): args_parser = argparse.ArgumentParser( description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) args_parser.add_argument( "filename", type=str, help="Path to an SDF or URDF file.") args_parser.add_argument( "--package_path", type=str, default=None, help="Full path to the root package for reading in SDF resources.") position_group = args_parser.add_mutually_exclusive_group() position_group.add_argument( "--position", type=float, nargs="+", default=[], help="A list of positions which must be the same length as the number " "of positions in the sdf model. Note that most models have a " "floating-base joint by default (unless the sdf explicitly welds " "the base to the world, and so have 7 positions corresponding to " "the quaternion representation of that floating-base position.") position_group.add_argument( "--joint_position", type=float, nargs="+", default=[], help="A list of positions which must be the same length as the number " "of positions ASSOCIATED WITH JOINTS in the sdf model. This " "does not include, e.g., floating-base coordinates, which will " "be assigned a default value.") args_parser.add_argument( "--test", action='store_true', help="Disable opening the gui window for testing.") args_parser.add_argument( "--visualize_collisions", action="store_true", help="Visualize the collision geometry in the visualizer. The " "collision geometries will be shown in red to differentiate " "them from the visual geometries.") # TODO(russt): Add option to weld the base to the world pending the # availability of GetUniqueBaseBody requested in #9747. MeshcatVisualizer.add_argparse_argument(args_parser) args = args_parser.parse_args() filename = args.filename if not os.path.isfile(filename): args_parser.error("File does not exist: {}".format(filename)) builder = DiagramBuilder() scene_graph = builder.AddSystem(SceneGraph()) # Construct a MultibodyPlant. plant = MultibodyPlant(0.0) plant.RegisterAsSourceForSceneGraph(scene_graph) # Create the parser. parser = Parser(plant) # Get the package pathname. if args.package_path: # Verify that package.xml is found in the designated path. package_path = os.path.abspath(args.package_path) if not os.path.isfile(os.path.join(package_path, "package.xml")): parser.error("package.xml not found at: {}".format(package_path)) # Get the package map and populate it using the package path. package_map = parser.package_map() package_map.PopulateFromFolder(package_path) # Add the model from the file and finalize the plant. parser.AddModelFromFile(filename) # Find all the geometries that have not already been marked as # 'illustration' (visual) and assume they are collision geometries. # Then add illustration properties to them that will draw them in red # and fifty percent translucent. if args.visualize_collisions: source_id = plant.get_source_id() red_illustration = MakePhongIllustrationProperties([1, 0, 0, 0.5]) for geometry_id in scene_graph.model_inspector().GetAllGeometryIds(): if(scene_graph.model_inspector().GetIllustrationProperties( geometry_id) is None): scene_graph.AssignRole( source_id, geometry_id, red_illustration) plant.Finalize() # Add sliders to set positions of the joints. sliders = builder.AddSystem(JointSliders(robot=plant)) to_pose = builder.AddSystem(MultibodyPositionToGeometryPose(plant)) builder.Connect(sliders.get_output_port(0), to_pose.get_input_port()) builder.Connect( to_pose.get_output_port(), scene_graph.get_source_pose_port(plant.get_source_id())) # Connect this to drake_visualizer. ConnectDrakeVisualizer(builder=builder, scene_graph=scene_graph) # Connect to Meshcat. if args.meshcat is not None: meshcat_viz = builder.AddSystem( MeshcatVisualizer(scene_graph, zmq_url=args.meshcat)) builder.Connect( scene_graph.get_pose_bundle_output_port(), meshcat_viz.get_input_port(0)) if len(args.position): sliders.set_position(args.position) elif len(args.joint_position): sliders.set_joint_position(args.joint_position) # Make the diagram and run it. diagram = builder.Build() simulator = Simulator(diagram) simulator.set_publish_every_time_step(False) if args.test: sliders.window.withdraw() simulator.AdvanceTo(0.1) else: simulator.set_target_realtime_rate(1.0) simulator.AdvanceTo(np.inf)
def test_warnings_and_errors(self): builder = DiagramBuilder() sg = builder.AddSystem(SceneGraph()) v1 = builder.AddSystem(MeshcatVisualizer(scene_graph=sg)) builder.Connect(sg.get_pose_bundle_output_port(), v1.get_input_port(0)) v1.set_name("v1") v2 = builder.AddSystem(MeshcatVisualizer(scene_graph=sg)) builder.Connect(sg.get_query_output_port(), v2.get_geometry_query_input_port()) v2.set_name("v2") v3 = builder.AddSystem(MeshcatVisualizer(scene_graph=None)) builder.Connect(sg.get_pose_bundle_output_port(), v3.get_input_port(0)) v3.set_name("v3") v4 = builder.AddSystem(MeshcatVisualizer(scene_graph=None)) builder.Connect(sg.get_query_output_port(), v4.get_geometry_query_input_port()) v4.set_name("v4") v5 = ConnectMeshcatVisualizer(builder, scene_graph=sg) v5.set_name("v5") v6 = ConnectMeshcatVisualizer( builder, scene_graph=sg, output_port=sg.get_pose_bundle_output_port()) v6.set_name("v6") v7 = ConnectMeshcatVisualizer( builder, scene_graph=sg, output_port=sg.get_query_output_port()) v7.set_name("v7") with self.assertRaises(AssertionError): v8 = ConnectMeshcatVisualizer(builder, scene_graph=None, output_port=None) v8.set_name("v8") v9 = ConnectMeshcatVisualizer( builder, scene_graph=None, output_port=sg.get_pose_bundle_output_port()) v9.set_name("v9") v10 = ConnectMeshcatVisualizer( builder, scene_graph=None, output_port=sg.get_query_output_port()) v10.set_name("v10") diagram = builder.Build() context = diagram.CreateDefaultContext() def PublishWithNoWarnings(v): with warnings.catch_warnings(record=True) as w: v.Publish(v.GetMyContextFromRoot(context)) self.assertEqual(len(w), 0, [x.message for x in w]) # Use pose_bundle API, give warning v1.load(v1.GetMyContextFromRoot(context)) with catch_drake_warnings(expected_count=1): v1.Publish(v1.GetMyContextFromRoot(context)) v1._warned_pose_bundle_input_port_connected = False v1.load() with catch_drake_warnings(expected_count=1): v1.Publish(v1.GetMyContextFromRoot(context)) # Use geometry_query API v2.load(v2.GetMyContextFromRoot(context)) PublishWithNoWarnings(v2) v2.load() PublishWithNoWarnings(v2) # Can't use pose_bundle API without passing a scene graph. with self.assertRaises(RuntimeError): v3.load(v3.GetMyContextFromRoot(context)) with self.assertRaises(RuntimeError): v3.load() # Use geometry_query API v4.load(v4.GetMyContextFromRoot(context)) PublishWithNoWarnings(v4) with self.assertRaises(RuntimeError): v4.load() # Can't work without scene_graph nor context. # Use geometry_query API v5.load(v5.GetMyContextFromRoot(context)) PublishWithNoWarnings(v5) v5.load() PublishWithNoWarnings(v5) # Use pose_bundle API, give warning v6.load(v6.GetMyContextFromRoot(context)) with catch_drake_warnings(expected_count=1): v6.Publish(v6.GetMyContextFromRoot(context)) v6._warned_pose_bundle_input_port_connected = False v6.load() with catch_drake_warnings(expected_count=1): v6.Publish(v6.GetMyContextFromRoot(context)) # Use geometry_query API v7.load(v7.GetMyContextFromRoot(context)) PublishWithNoWarnings(v7) v7.load() PublishWithNoWarnings(v7) # Can't use pose_bundle API without passing a scene graph. with self.assertRaises(RuntimeError): v9.load(v9.GetMyContextFromRoot(context)) with self.assertRaises(RuntimeError): v9.load() # Use geometry_query API v10.load(v10.GetMyContextFromRoot(context)) PublishWithNoWarnings(v10) with self.assertRaises(RuntimeError): v10.load() # Can't work without scene_graph nor context.
def main(): goal_position = np.array([0.5, 0., 0.025]) blue_box_clean_position = [0.4, 0., 0.05] red_box_clean_position = [0.6, 0., 0.05] goal_delta = 0.05 parser = argparse.ArgumentParser(description=__doc__) MeshcatVisualizer.add_argparse_argument(parser) parser.add_argument('--use_meshcat', action='store_true', help="Must be set for meshcat to be used.") parser.add_argument('--disable_planar_viz', action='store_true', help="Don't create a planar visualizer. Probably" " breaks something that assumes the planar" " vis exists.") parser.add_argument('--teleop', action='store_true', help="Enable teleop, so *don't* use the state machine" " and motion primitives.") args = parser.parse_args() builder = DiagramBuilder() # Set up the ManipulationStation station = builder.AddSystem(ManipulationStation(0.001)) mbp = station.get_multibody_plant() station.SetupManipulationClassStation() add_goal_region_visual_geometry(mbp, goal_position, goal_delta) # add_box_at_location(mbp, name="blue_box", color=[0.25, 0.25, 1., 1.], # pose=RigidTransform(p=[0.4, 0.0, 0.025])) # add_box_at_location(mbp, name="red_box", color=[1., 0.25, 0.25, 1.], # pose=RigidTransform(p=[0.6, 0.0, 0.025])) add_box_at_location( mbp, name="blue_box", color=[0.25, 0.25, 1., 1.], pose=RigidTransform( p=[0.4 + 0.05 * (np.random.uniform() * 2 - 1), 0.0, 0.025])) add_box_at_location( mbp, name="red_box", color=[1., 0.25, 0.25, 1.], pose=RigidTransform( p=[0.6 + 0.05 * (np.random.uniform() * 2 - 1), 0.0, 0.025])) station.Finalize() iiwa_q0 = np.array([0.0, 0.6, 0.0, -1.75, 0., 1., np.pi / 2.]) # Attach a visualizer. if args.use_meshcat: meshcat = builder.AddSystem( MeshcatVisualizer(station.get_scene_graph(), zmq_url=args.meshcat)) builder.Connect(station.GetOutputPort("pose_bundle"), meshcat.get_input_port(0)) if not args.disable_planar_viz: plt.gca().clear() planar_visualizer = PlanarSceneGraphVisualizer( station.get_scene_graph(), xlim=[0.25, 0.8], ylim=[-0.1, 0.5], ax=plt.gca()) viz = builder.AddSystem(planar_visualizer) builder.Connect(station.GetOutputPort("pose_bundle"), viz.get_input_port(0)) plt.draw() # Hook up DifferentialIK, since both control modes use it. robot = station.get_controller_plant() params = DifferentialInverseKinematicsParameters(robot.num_positions(), robot.num_velocities()) time_step = 0.005 params.set_timestep(time_step) # True velocity limits for the IIWA14 (in rad, rounded down to the first # decimal) iiwa14_velocity_limits = np.array([1.4, 1.4, 1.7, 1.3, 2.2, 2.3, 2.3]) # Stay within a small fraction of those limits for this teleop demo. factor = 1.0 params.set_joint_velocity_limits( (-factor * iiwa14_velocity_limits, factor * iiwa14_velocity_limits)) differential_ik = builder.AddSystem( DifferentialIK(robot, robot.GetFrameByName("iiwa_link_7"), params, time_step)) differential_ik.set_name("Differential IK") differential_ik.parameters.set_nominal_joint_position(iiwa_q0) builder.Connect(differential_ik.GetOutputPort("joint_position_desired"), station.GetInputPort("iiwa_position")) if not args.teleop: symbol_list = [ SymbolL2Close("blue_box_in_goal", "blue_box", goal_position, goal_delta), SymbolL2Close("red_box_in_goal", "red_box", goal_position, goal_delta), SymbolRelativePositionL2("blue_box_on_red_box", "blue_box", "red_box", l2_thresh=0.01, offset=np.array([0., 0., 0.05])), SymbolRelativePositionL2("red_box_on_blue_box", "red_box", "blue_box", l2_thresh=0.01, offset=np.array([0., 0., 0.05])), ] primitive_list = [ MoveBoxPrimitive("put_blue_box_in_goal", mbp, "blue_box", goal_position), MoveBoxPrimitive("put_red_box_in_goal", mbp, "red_box", goal_position), MoveBoxPrimitive("put_blue_box_away", mbp, "blue_box", blue_box_clean_position), MoveBoxPrimitive("put_red_box_away", mbp, "red_box", red_box_clean_position), MoveBoxPrimitive("put_red_box_on_blue_box", mbp, "red_box", np.array([0., 0., 0.05]), "blue_box"), MoveBoxPrimitive("put_blue_box_on_red_box", mbp, "blue_box", np.array([0., 0., 0.05]), "red_box"), ] task_execution_system = builder.AddSystem( TaskExectionSystem( mbp, symbol_list=symbol_list, primitive_list=primitive_list, dfa_json_file="specifications/red_and_blue_boxes_stacking.json" )) builder.Connect(station.GetOutputPort("plant_continuous_state"), task_execution_system.GetInputPort("mbp_state_vector")) builder.Connect(task_execution_system.get_output_port(0), differential_ik.GetInputPort("rpy_xyz_desired")) builder.Connect(task_execution_system.get_output_port(1), station.GetInputPort("wsg_position")) #movebox = MoveBoxPrimitive("test_move_box", mbp, "red_box", goal_position) #rpy_xyz_trajectory, gripper_traj = movebox.generate_rpyxyz_and_gripper_trajectory(mbp.CreateDefaultContext()) #rpy_xyz_trajectory_source = builder.AddSystem(TrajectorySource(rpy_xyz_trajectory)) #builder.Connect(rpy_xyz_trajectory_source.get_output_port(0), # differential_ik.GetInputPort("rpy_xyz_desired")) #wsg_position_source = builder.AddSystem(TrajectorySource(gripper_traj)) #builder.Connect(wsg_position_source.get_output_port(0), # station.GetInputPort("wsg_position")) # Target zero feedforward residual torque at all times. fft = builder.AddSystem(ConstantVectorSource(np.zeros(7))) builder.Connect(fft.get_output_port(0), station.GetInputPort("iiwa_feedforward_torque")) input_force_fix = builder.AddSystem(ConstantVectorSource([40.0])) builder.Connect(input_force_fix.get_output_port(0), station.GetInputPort("wsg_force_limit")) end_time = 20 else: # Set up teleoperation. # Hook up a pygame-based keyboard+mouse interface for # teleoperation, and low pass its output to drive the EE target # for the differential IK. print_instructions() teleop = builder.AddSystem(MouseKeyboardTeleop(grab_focus=True)) filter_ = builder.AddSystem( FirstOrderLowPassFilter(time_constant=0.005, size=6)) builder.Connect(teleop.get_output_port(0), filter_.get_input_port(0)) builder.Connect(filter_.get_output_port(0), differential_ik.GetInputPort("rpy_xyz_desired")) builder.Connect(teleop.GetOutputPort("position"), station.GetInputPort("wsg_position")) builder.Connect(teleop.GetOutputPort("force_limit"), station.GetInputPort("wsg_force_limit")) # Target zero feedforward residual torque at all times. fft = builder.AddSystem(ConstantVectorSource(np.zeros(7))) builder.Connect(fft.get_output_port(0), station.GetInputPort("iiwa_feedforward_torque")) # Simulate functionally forever. end_time = 10000 # Create symbol log #symbol_log = SymbolFromTransformLog( # [SymbolL2Close('at_goal', 'red_box', goal_position, .025), # SymbolL2Close('at_goal', 'blue_box', goal_position, .025)]) # #symbol_logger_system = builder.AddSystem( # SymbolLoggerSystem( # station.get_multibody_plant(), symbol_logger=symbol_log)) #builder.Connect( # station.GetOutputPort("plant_continuous_state"), # symbol_logger_system.GetInputPort("mbp_state_vector")) # Remaining input ports need to be tied up. diagram = builder.Build() g = pydot.graph_from_dot_data(diagram.GetGraphvizString())[0] g.write_png("system_diagram.png") diagram_context = diagram.CreateDefaultContext() station_context = diagram.GetMutableSubsystemContext( station, diagram_context) station.SetIiwaPosition(station_context, iiwa_q0) differential_ik.SetPositions( diagram.GetMutableSubsystemContext(differential_ik, diagram_context), iiwa_q0) if args.teleop: teleop.SetPose(differential_ik.ForwardKinematics(iiwa_q0)) filter_.set_initial_output_value( diagram.GetMutableSubsystemContext(filter_, diagram_context), teleop.get_output_port(0).Eval( diagram.GetMutableSubsystemContext(teleop, diagram_context))) simulator = Simulator(diagram, diagram_context) simulator.set_publish_every_time_step(False) simulator.set_target_realtime_rate(1.0) # video_recorder = PyPlotVisualizer(ax=plt.gca()) planar_visualizer.start_recording() simulator.AdvanceTo(end_time) recording = planar_visualizer.get_recording() recording.save('video_%s.mp4' % str(datetime.datetime.now()).replace(' ', '_'))
def main(): parser = argparse.ArgumentParser(description=__doc__) parser.add_argument( "--target_realtime_rate", type=float, default=1.0, help="Desired rate relative to real time. See documentation for " "Simulator::set_target_realtime_rate() for details.", ) parser.add_argument( "--simulation_time", type=float, default=10.0, help="Desired duration of the simulation in seconds.", ) parser.add_argument( "--time_step", type=float, default=0.0, help="If greater than zero, the plant is modeled as a system with " "discrete updates and period equal to this time_step. " "If 0, the plant is modeled as a continuous system.", ) args = parser.parse_args() file_name = FindResourceOrThrow( "drake/examples/multibody/cart_pole/cart_pole.sdf") builder = DiagramBuilder() scene_graph = builder.AddSystem(SceneGraph()) cart_pole = builder.AddSystem(MultibodyPlant(time_step=args.time_step)) cart_pole.RegisterAsSourceForSceneGraph(scene_graph) Parser(plant=cart_pole).AddModelFromFile(file_name) cart_pole.AddForceElement(UniformGravityFieldElement()) cart_pole.Finalize() assert cart_pole.geometry_source_is_registered() builder.Connect(scene_graph.get_query_output_port(), cart_pole.get_geometry_query_input_port()) builder.Connect( cart_pole.get_geometry_poses_output_port(), scene_graph.get_source_pose_port(cart_pole.get_source_id()), ) ConnectDrakeVisualizer(builder=builder, scene_graph=scene_graph) diagram = builder.Build() diagram_context = diagram.CreateDefaultContext() cart_pole_context = diagram.GetMutableSubsystemContext( cart_pole, diagram_context) cart_pole_context.FixInputPort( cart_pole.get_actuation_input_port().get_index(), [0]) cart_slider = cart_pole.GetJointByName("CartSlider") pole_pin = cart_pole.GetJointByName("PolePin") cart_slider.set_translation(context=cart_pole_context, translation=0.0) pole_pin.set_angle(context=cart_pole_context, angle=2.0) simulator = Simulator(diagram, diagram_context) simulator.set_publish_every_time_step(False) simulator.set_target_realtime_rate(args.target_realtime_rate) simulator.Initialize() simulator.AdvanceTo(args.simulation_time)
def main(): parser = argparse.ArgumentParser(description=__doc__) parser.add_argument( "--target_realtime_rate", type=float, default=1.0, help="Desired rate relative to real time. See documentation for " "Simulator::set_target_realtime_rate() for details.") parser.add_argument("--duration", type=float, default=np.inf, help="Desired duration of the simulation in seconds.") parser.add_argument( "--hardware", action='store_true', help="Use the ManipulationStationHardwareInterface instead of an " "in-process simulation.") parser.add_argument("--test", action='store_true', help="Disable opening the gui window for testing.") parser.add_argument( '--setup', type=str, default='manipulation_class', help="The manipulation station setup to simulate. ", choices=['manipulation_class', 'clutter_clearing', 'planar']) parser.add_argument( "-w", "--open-window", dest="browser_new", action="store_const", const=1, default=None, help="Open the MeshCat display in a new browser window.") args = parser.parse_args() builder = DiagramBuilder() # NOTE: the meshcat instance is always created in order to create the # teleop controls (joint sliders and open/close gripper button). When # args.hardware is True, the meshcat server will *not* display robot # geometry, but it will contain the joint sliders and open/close gripper # button in the "Open Controls" tab in the top-right of the viewing server. meshcat = Meshcat() if args.hardware: # TODO(russt): Replace this hard-coded camera serial number with a # config file. camera_ids = ["805212060544"] station = builder.AddSystem( ManipulationStationHardwareInterface(camera_ids)) station.Connect(wait_for_cameras=False) else: station = builder.AddSystem(ManipulationStation()) # Initializes the chosen station type. if args.setup == 'manipulation_class': station.SetupManipulationClassStation() station.AddManipulandFromFile( "drake/examples/manipulation_station/models/" + "061_foam_brick.sdf", RigidTransform(RotationMatrix.Identity(), [0.6, 0, 0])) elif args.setup == 'clutter_clearing': station.SetupClutterClearingStation() ycb_objects = CreateClutterClearingYcbObjectList() for model_file, X_WObject in ycb_objects: station.AddManipulandFromFile(model_file, X_WObject) elif args.setup == 'planar': station.SetupPlanarIiwaStation() station.AddManipulandFromFile( "drake/examples/manipulation_station/models/" + "061_foam_brick.sdf", RigidTransform(RotationMatrix.Identity(), [0.6, 0, 0])) station.Finalize() geometry_query_port = station.GetOutputPort("geometry_query") DrakeVisualizer.AddToBuilder(builder, geometry_query_port) meshcat_visualizer = MeshcatVisualizer.AddToBuilder( builder=builder, query_object_port=geometry_query_port, meshcat=meshcat) if args.setup == 'planar': meshcat.Set2dRenderMode() if args.browser_new is not None: url = meshcat.web_url() webbrowser.open(url=url, new=args.browser_new) teleop = builder.AddSystem( JointSliders(meshcat=meshcat, plant=station.get_controller_plant())) num_iiwa_joints = station.num_iiwa_joints() filter = builder.AddSystem( FirstOrderLowPassFilter(time_constant=2.0, size=num_iiwa_joints)) builder.Connect(teleop.get_output_port(0), filter.get_input_port(0)) builder.Connect(filter.get_output_port(0), station.GetInputPort("iiwa_position")) wsg_buttons = builder.AddSystem(SchunkWsgButtons(meshcat=meshcat)) builder.Connect(wsg_buttons.GetOutputPort("position"), station.GetInputPort("wsg_position")) builder.Connect(wsg_buttons.GetOutputPort("force_limit"), station.GetInputPort("wsg_force_limit")) # When in regression test mode, log our joint velocities to later check # that they were sufficiently quiet. if args.test: iiwa_velocities = builder.AddSystem(VectorLogSink(num_iiwa_joints)) builder.Connect(station.GetOutputPort("iiwa_velocity_estimated"), iiwa_velocities.get_input_port(0)) else: iiwa_velocities = None diagram = builder.Build() simulator = Simulator(diagram) # This is important to avoid duplicate publishes to the hardware interface: simulator.set_publish_every_time_step(False) station_context = diagram.GetMutableSubsystemContext( station, simulator.get_mutable_context()) station.GetInputPort("iiwa_feedforward_torque").FixValue( station_context, np.zeros(num_iiwa_joints)) # If the diagram is only the hardware interface, then we must advance it a # little bit so that first LCM messages get processed. A simulated plant is # already publishing correct positions even without advancing, and indeed # we must not advance a simulated plant until the sliders and filters have # been initialized to match the plant. if args.hardware: simulator.AdvanceTo(1e-6) # Eval the output port once to read the initial positions of the IIWA. q0 = station.GetOutputPort("iiwa_position_measured").Eval(station_context) teleop.SetPositions(q0) filter.set_initial_output_value( diagram.GetMutableSubsystemContext(filter, simulator.get_mutable_context()), q0) simulator.set_target_realtime_rate(args.target_realtime_rate) simulator.AdvanceTo(args.duration) # Ensure that our initialization logic was correct, by inspecting our # logged joint velocities. if args.test: iiwa_velocities_log = iiwa_velocities.FindLog(simulator.get_context()) for time, qdot in zip(iiwa_velocities_log.sample_times(), iiwa_velocities_log.data().transpose()): # TODO(jwnimmer-tri) We should be able to do better than a 40 # rad/sec limit, but that's the best we can enforce for now. if qdot.max() > 0.1: print(f"ERROR: large qdot {qdot} at time {time}") sys.exit(1)
def test_decomposition_controller_like_workflow(self): """Tests subgraphs (post-finalize) for decomposition, with a scene-graph. Also shows a workflow of replacing joints / welding joints.""" builder = DiagramBuilder() # N.B. I (Eric) am using ManipulationStation because it's currently # the simplest way to get a complex scene in pydrake. station = ManipulationStation(time_step=0.001) station.SetupManipulationClassStation() station.Finalize() builder.AddSystem(station) plant = station.get_multibody_plant() scene_graph = station.get_scene_graph() iiwa = plant.GetModelInstanceByName("iiwa") wsg = plant.GetModelInstanceByName("gripper") if VISUALIZE: print("test_decomposition_controller_like_workflow") ConnectDrakeVisualizer(builder, scene_graph, station.GetOutputPort("pose_bundle")) diagram = builder.Build() # Set the context with which things should be computed. d_context = diagram.CreateDefaultContext() context = plant.GetMyContextFromRoot(d_context) q_iiwa = [0.3, 0.7, 0.3, 0.6, 0.5, 0.6, 0.7] q_wsg = [-0.03, 0.03] plant.SetPositions(context, iiwa, q_iiwa) plant.SetPositions(context, wsg, q_wsg) # Build and visualize. control_builder = DiagramBuilder() control_plant, control_scene_graph = AddMultibodyPlantSceneGraph( control_builder, time_step=0.) if VISUALIZE: ConnectDrakeVisualizer(control_builder, control_scene_graph) # N.B. This has the same scene, but with all joints outside of the # IIWA frozen. to_control = mut.add_plant_with_articulated_subset_to( plant_src=plant, scene_graph_src=scene_graph, articulated_models_src=[iiwa], context_src=context, plant_dest=control_plant, scene_graph_dest=control_scene_graph) self.assertIsInstance(to_control, mut.MultibodyPlantElementsMap) control_plant.Finalize() self.assertEqual(control_plant.num_positions(), plant.num_positions(iiwa)) control_diagram = control_builder.Build() control_d_context = control_diagram.CreateDefaultContext() control_context = control_plant.GetMyContextFromRoot(control_d_context) to_control.copy_state(context, control_context) util.compare_frames(plant, context, control_plant, control_context, "iiwa_link_0", "iiwa_link_7") util.compare_frames(plant, context, control_plant, control_context, "body", "left_finger") # Visualize. if VISUALIZE: print(" Visualize original plant") Simulator(diagram, d_context.Clone()).Initialize() input(" Press enter...") print(" Visualize control plant") Simulator(control_diagram, control_d_context.Clone()).Initialize() input(" Press enter...") # For grins, ensure that we can copy everything, including world weld. control_plant_copy = MultibodyPlant(time_step=0.) subgraph = mut.MultibodyPlantSubgraph( mut.get_elements_from_plant(control_plant)) subgraph.add_to(control_plant_copy) control_plant_copy.Finalize() self.assertEqual(control_plant_copy.num_positions(), control_plant.num_positions()) util.assert_plant_equals(control_plant, None, control_plant_copy, None)
def test_drake_visualizer(self): # Test visualization API. T = float SceneGraph = mut.SceneGraph_[T] DiagramBuilder = DiagramBuilder_[T] Simulator = Simulator_[T] lcm = DrakeLcm() role = mut.Role.kIllustration params = mut.DrakeVisualizerParams(publish_period=0.1, role=mut.Role.kIllustration, default_color=mut.Rgba( 0.1, 0.2, 0.3, 0.4)) # Add some subscribers to detect message broadcast. load_channel = "DRAKE_VIEWER_LOAD_ROBOT" draw_channel = "DRAKE_VIEWER_DRAW" load_subscriber = Subscriber(lcm, load_channel, lcmt_viewer_load_robot) draw_subscriber = Subscriber(lcm, draw_channel, lcmt_viewer_draw) # There are three ways to configure DrakeVisualizer. def by_hand(builder, scene_graph, params): visualizer = builder.AddSystem( mut.DrakeVisualizer(lcm=lcm, params=params)) builder.Connect(scene_graph.get_query_output_port(), visualizer.query_object_input_port()) def auto_connect_to_system(builder, scene_graph, params): mut.DrakeVisualizer.AddToBuilder(builder=builder, scene_graph=scene_graph, lcm=lcm, params=params) def auto_connect_to_port(builder, scene_graph, params): mut.DrakeVisualizer.AddToBuilder( builder=builder, query_object_port=scene_graph.get_query_output_port(), lcm=lcm, params=params) for func in [by_hand, auto_connect_to_system, auto_connect_to_port]: # Build the diagram. builder = DiagramBuilder() scene_graph = builder.AddSystem(SceneGraph()) func(builder, scene_graph, params) # Simulate to t = 0 to send initial load and draw messages. diagram = builder.Build() Simulator(diagram).AdvanceTo(0) lcm.HandleSubscriptions(0) self.assertEqual(load_subscriber.count, 1) self.assertEqual(draw_subscriber.count, 1) load_subscriber.clear() draw_subscriber.clear() # Ad hoc broadcasting. scene_graph = SceneGraph() mut.DrakeVisualizer.DispatchLoadMessage(scene_graph, lcm, params) lcm.HandleSubscriptions(0) self.assertEqual(load_subscriber.count, 1) self.assertEqual(draw_subscriber.count, 0) load_subscriber.clear() draw_subscriber.clear()
def test_context_api(self): # Capture miscellaneous functions not yet tested. model_value = AbstractValue.Make("Hello") model_vector = BasicVector([1., 2.]) class TrivialSystem(LeafSystem): def __init__(self): LeafSystem.__init__(self) self.DeclareContinuousState(1) self.DeclareDiscreteState(2) self.DeclareAbstractState(model_value.Clone()) self.DeclareAbstractParameter(model_value.Clone()) self.DeclareNumericParameter(model_vector.Clone()) system = TrivialSystem() context = system.CreateDefaultContext() self.assertTrue(context.get_state() is context.get_mutable_state()) self.assertEqual(context.num_continuous_states(), 1) self.assertTrue(context.get_continuous_state_vector() is context.get_mutable_continuous_state_vector()) self.assertEqual(context.num_discrete_state_groups(), 1) self.assertTrue(context.get_discrete_state_vector() is context.get_mutable_discrete_state_vector()) self.assertTrue( context.get_discrete_state(0) is context.get_discrete_state_vector()) self.assertTrue( context.get_discrete_state(0) is context.get_discrete_state().get_vector(0)) self.assertTrue( context.get_mutable_discrete_state(0) is context.get_mutable_discrete_state_vector()) self.assertTrue( context.get_mutable_discrete_state(0) is context.get_mutable_discrete_state().get_vector(0)) self.assertEqual(context.num_abstract_states(), 1) self.assertTrue(context.get_abstract_state() is context.get_mutable_abstract_state()) self.assertTrue( context.get_abstract_state(0) is context.get_mutable_abstract_state(0)) self.assertEqual( context.get_abstract_state(0).get_value(), model_value.get_value()) # Check abstract state API (also test AbstractValues). values = context.get_abstract_state() self.assertEqual(values.size(), 1) self.assertEqual( values.get_value(0).get_value(), model_value.get_value()) self.assertEqual( values.get_mutable_value(0).get_value(), model_value.get_value()) values.SetFrom(values.Clone()) # Check parameter accessors. self.assertEqual(system.num_abstract_parameters(), 1) self.assertEqual( context.get_abstract_parameter(index=0).get_value(), model_value.get_value()) self.assertEqual(system.num_numeric_parameter_groups(), 1) np.testing.assert_equal( context.get_numeric_parameter(index=0).get_value(), model_vector.get_value()) # Check diagram context accessors. builder = DiagramBuilder() builder.AddSystem(system) diagram = builder.Build() context = diagram.CreateDefaultContext() # Existence check. self.assertIsNot(diagram.GetMutableSubsystemState(system, context), None) subcontext = diagram.GetMutableSubsystemContext(system, context) self.assertIsNot(subcontext, None) self.assertIs(diagram.GetSubsystemContext(system, context), subcontext)
def test_render_engine_api(self): class DummyRenderEngine(mut.render.RenderEngine): """Mirror of C++ DummyRenderEngine.""" # See comment below about `rgbd_sensor_test.cc`. latest_instance = None def __init__(self, render_label=None): mut.render.RenderEngine.__init__(self) # N.B. We do not hide these because this is a test class. # Normally, you would want to hide this. self.force_accept = False self.registered_geometries = set() self.updated_ids = {} self.include_group_name = "in_test" self.X_WC = RigidTransform_[float]() self.color_count = 0 self.depth_count = 0 self.label_count = 0 self.color_camera = None self.depth_camera = None self.label_camera = None def UpdateViewpoint(self, X_WC): DummyRenderEngine.latest_instance = self self.X_WC = X_WC def ImplementGeometry(self, shape, user_data): DummyRenderEngine.latest_instance = self def DoRegisterVisual(self, id, shape, properties, X_WG): DummyRenderEngine.latest_instance = self mut.GetRenderLabelOrThrow(properties) if self.force_accept or properties.HasGroup( self.include_group_name): self.registered_geometries.add(id) return True return False def DoUpdateVisualPose(self, id, X_WG): DummyRenderEngine.latest_instance = self self.updated_ids[id] = X_WG def DoRemoveGeometry(self, id): DummyRenderEngine.latest_instance = self self.registered_geometries.remove(id) def DoClone(self): DummyRenderEngine.latest_instance = self new = DummyRenderEngine() new.force_accept = copy.copy(self.force_accept) new.registered_geometries = copy.copy( self.registered_geometries) new.updated_ids = copy.copy(self.updated_ids) new.include_group_name = copy.copy(self.include_group_name) new.X_WC = copy.copy(self.X_WC) new.color_count = copy.copy(self.color_count) new.depth_count = copy.copy(self.depth_count) new.label_count = copy.copy(self.label_count) new.color_camera = copy.copy(self.color_camera) new.depth_camera = copy.copy(self.depth_camera) new.label_camera = copy.copy(self.label_camera) return new def DoRenderColorImage(self, camera, color_image_out): DummyRenderEngine.latest_instance = self self.color_count += 1 self.color_camera = camera def DoRenderDepthImage(self, camera, depth_image_out): DummyRenderEngine.latest_instance = self self.depth_count += 1 self.depth_camera = camera def DoRenderLabelImage(self, camera, label_image_out): DummyRenderEngine.latest_instance = self self.label_count += 1 self.label_camera = camera engine = DummyRenderEngine() self.assertIsInstance(engine, mut.render.RenderEngine) self.assertIsInstance(engine.Clone(), DummyRenderEngine) # Test implementation of C++ interface by using RgbdSensor. renderer_name = "renderer" builder = DiagramBuilder() scene_graph = builder.AddSystem(mut.SceneGraph()) # N.B. This passes ownership. scene_graph.AddRenderer(renderer_name, engine) sensor = builder.AddSystem( RgbdSensor(parent_id=scene_graph.world_frame_id(), X_PB=RigidTransform(), depth_camera=mut.render.DepthRenderCamera( mut.render.RenderCameraCore( renderer_name, CameraInfo(640, 480, np.pi / 4), mut.render.ClippingRange(0.1, 5.0), RigidTransform()), mut.render.DepthRange(0.1, 5.0)))) builder.Connect( scene_graph.get_query_output_port(), sensor.query_object_input_port(), ) diagram = builder.Build() diagram_context = diagram.CreateDefaultContext() sensor_context = sensor.GetMyContextFromRoot(diagram_context) image = sensor.color_image_output_port().Eval(sensor_context) # N.B. Because there's context cloning going on under the hood, we # won't be interacting with our originally registered instance. # See `rgbd_sensor_test.cc` as well. current_engine = DummyRenderEngine.latest_instance self.assertIsNot(current_engine, engine) self.assertIsInstance(image, ImageRgba8U) self.assertEqual(current_engine.color_count, 1) image = sensor.depth_image_32F_output_port().Eval(sensor_context) self.assertIsInstance(image, ImageDepth32F) self.assertEqual(current_engine.depth_count, 1) image = sensor.depth_image_16U_output_port().Eval(sensor_context) self.assertIsInstance(image, ImageDepth16U) self.assertEqual(current_engine.depth_count, 2) image = sensor.label_image_output_port().Eval(sensor_context) self.assertIsInstance(image, ImageLabel16I) self.assertEqual(current_engine.label_count, 1) # Confirm that the CameraProperties APIs are *not* available. with catch_drake_warnings(expected_count=2): cam = mut.render.CameraProperties(10, 10, np.pi / 4, "") depth_cam = mut.render.DepthCameraProperties( 10, 10, np.pi / 4, "", 0.1, 5) with self.assertRaises(TypeError): engine.RenderColorImage(cam, True, ImageRgba8U(cam.width, cam.height)) with self.assertRaises(TypeError): engine.RenderLabelImage(cam, True, ImageLabel16I(cam.width, cam.height)) with self.assertRaises(TypeError): engine.RenderDepthImage( depth_cam, True, ImageDepth32F(depth_cam.width, depth_cam.height))
def main(): parser = argparse.ArgumentParser(description=__doc__) parser.add_argument( "--target_realtime_rate", type=float, default=1.0, help="Desired rate relative to real time. See documentation for " "Simulator::set_target_realtime_rate() for details.") parser.add_argument("--duration", type=float, default=np.inf, help="Desired duration of the simulation in seconds.") parser.add_argument( "--hardware", action='store_true', help="Use the ManipulationStationHardwareInterface instead of an " "in-process simulation.") parser.add_argument("--test", action='store_true', help="Disable opening the gui window for testing.") parser.add_argument( "--filter_time_const", type=float, default=0.005, help="Time constant for the first order low pass filter applied to" "the teleop commands") parser.add_argument( "--velocity_limit_factor", type=float, default=1.0, help="This value, typically between 0 and 1, further limits the " "iiwa14 joint velocities. It multiplies each of the seven " "pre-defined joint velocity limits. " "Note: The pre-defined velocity limits are specified by " "iiwa14_velocity_limits, found in this python file.") parser.add_argument('--setup', type=str, default='manipulation_class', help="The manipulation station setup to simulate. ", choices=['manipulation_class', 'clutter_clearing']) MeshcatVisualizer.add_argparse_argument(parser) args = parser.parse_args() if args.test: # Don't grab mouse focus during testing. grab_focus = False # See: https://stackoverflow.com/a/52528832/7829525 os.environ["SDL_VIDEODRIVER"] = "dummy" else: grab_focus = True builder = DiagramBuilder() if args.hardware: station = builder.AddSystem(ManipulationStationHardwareInterface()) station.Connect(wait_for_cameras=False) else: station = builder.AddSystem(ManipulationStation()) # Initializes the chosen station type. if args.setup == 'manipulation_class': station.SetupManipulationClassStation() station.AddManipulandFromFile( ("drake/examples/manipulation_station/models/" "061_foam_brick.sdf"), RigidTransform(RotationMatrix.Identity(), [0.6, 0, 0])) elif args.setup == 'clutter_clearing': station.SetupClutterClearingStation() ycb_objects = CreateClutterClearingYcbObjectList() for model_file, X_WObject in ycb_objects: station.AddManipulandFromFile(model_file, X_WObject) station.Finalize() ConnectDrakeVisualizer(builder, station.get_scene_graph(), station.GetOutputPort("pose_bundle")) if args.meshcat: meshcat = builder.AddSystem( MeshcatVisualizer(station.get_scene_graph(), zmq_url=args.meshcat)) builder.Connect(station.GetOutputPort("pose_bundle"), meshcat.get_input_port(0)) robot = station.get_controller_plant() params = DifferentialInverseKinematicsParameters(robot.num_positions(), robot.num_velocities()) time_step = 0.005 params.set_timestep(time_step) # True velocity limits for the IIWA14 (in rad, rounded down to the first # decimal) iiwa14_velocity_limits = np.array([1.4, 1.4, 1.7, 1.3, 2.2, 2.3, 2.3]) # Stay within a small fraction of those limits for this teleop demo. factor = args.velocity_limit_factor params.set_joint_velocity_limits( (-factor * iiwa14_velocity_limits, factor * iiwa14_velocity_limits)) differential_ik = builder.AddSystem( DifferentialIK(robot, robot.GetFrameByName("iiwa_link_7"), params, time_step)) builder.Connect(differential_ik.GetOutputPort("joint_position_desired"), station.GetInputPort("iiwa_position")) teleop = builder.AddSystem(MouseKeyboardTeleop(grab_focus=grab_focus)) filter_ = builder.AddSystem( FirstOrderLowPassFilter(time_constant=args.filter_time_const, size=6)) builder.Connect(teleop.get_output_port(0), filter_.get_input_port(0)) builder.Connect(filter_.get_output_port(0), differential_ik.GetInputPort("rpy_xyz_desired")) builder.Connect(teleop.GetOutputPort("position"), station.GetInputPort("wsg_position")) builder.Connect(teleop.GetOutputPort("force_limit"), station.GetInputPort("wsg_force_limit")) diagram = builder.Build() simulator = Simulator(diagram) # This is important to avoid duplicate publishes to the hardware interface: simulator.set_publish_every_time_step(False) station_context = diagram.GetMutableSubsystemContext( station, simulator.get_mutable_context()) station.GetInputPort("iiwa_feedforward_torque").FixValue( station_context, np.zeros(7)) # If the diagram is only the hardware interface, then we must advance it a # little bit so that first LCM messages get processed. A simulated plant is # already publishing correct positions even without advancing, and indeed # we must not advance a simulated plant until the sliders and filters have # been initialized to match the plant. if args.hardware: simulator.AdvanceTo(1e-6) q0 = station.GetOutputPort("iiwa_position_measured").Eval(station_context) differential_ik.parameters.set_nominal_joint_position(q0) teleop.SetPose(differential_ik.ForwardKinematics(q0)) filter_.set_initial_output_value( diagram.GetMutableSubsystemContext(filter_, simulator.get_mutable_context()), teleop.get_output_port(0).Eval( diagram.GetMutableSubsystemContext( teleop, simulator.get_mutable_context()))) differential_ik.SetPositions( diagram.GetMutableSubsystemContext(differential_ik, simulator.get_mutable_context()), q0) simulator.set_target_realtime_rate(args.target_realtime_rate) print_instructions() simulator.AdvanceTo(args.duration)
def do_main(): rospy.init_node('run_dishrack_interaction', anonymous=False) #np.random.seed(42) for outer_iter in range(200): try: builder = DiagramBuilder() mbp, scene_graph = AddMultibodyPlantSceneGraph( builder, MultibodyPlant(time_step=0.0025)) # Add ground world_body = mbp.world_body() ground_shape = Box(2., 2., 2.) ground_body = mbp.AddRigidBody( "ground", SpatialInertia(mass=10.0, p_PScm_E=np.array([0., 0., 0.]), G_SP_E=UnitInertia(1.0, 1.0, 1.0))) mbp.WeldFrames(world_body.body_frame(), ground_body.body_frame(), RigidTransform(p=[0, 0, -1])) mbp.RegisterVisualGeometry(ground_body, RigidTransform.Identity(), ground_shape, "ground_vis", np.array([0.5, 0.5, 0.5, 1.])) mbp.RegisterCollisionGeometry(ground_body, RigidTransform.Identity(), ground_shape, "ground_col", CoulombFriction(0.9, 0.8)) parser = Parser(mbp, scene_graph) dish_bin_model = "/home/gizatt/projects/scene_generation/models/dish_models/bus_tub_01_decomp/bus_tub_01_decomp.urdf" cupboard_model = "/home/gizatt/projects/scene_generation/models/dish_models/shelf_two_levels.sdf" candidate_model_files = { #"mug": "/home/gizatt/drake/manipulation/models/mug/mug.urdf", "mug_1": "/home/gizatt/projects/scene_generation/models/dish_models/mug_1_decomp/mug_1_decomp.urdf", #"plate_11in": "/home/gizatt/drake/manipulation/models/dish_models/plate_11in_decomp/plate_11in_decomp.urdf", #"/home/gizatt/drake/manipulation/models/mug_big/mug_big.urdf", #"/home/gizatt/drake/manipulation/models/dish_models/bowl_6p25in_decomp/bowl_6p25in_decomp.urdf", #"/home/gizatt/drake/manipulation/models/dish_models/plate_8p5in_decomp/plate_8p5in_decomp.urdf", } # Decide how many of each object to add max_num_objs = 6 num_objs = [ np.random.randint(0, max_num_objs) for k in range(len(candidate_model_files.keys())) ] # Actually produce their initial poses + add them to the sim poses = [] # [quat, pos] all_object_instances = [] all_manipulable_body_ids = [] total_num_objs = sum(num_objs) object_ordering = list(range(total_num_objs)) k = 0 random.shuffle(object_ordering) print("ordering: ", object_ordering) for class_k, class_entry in enumerate( candidate_model_files.items()): for model_instance_k in range(num_objs[class_k]): class_name, class_path = class_entry model_name = "%s_%d" % (class_name, model_instance_k) all_object_instances.append([class_name, model_name]) model_id = parser.AddModelFromFile(class_path, model_name=model_name) all_manipulable_body_ids += mbp.GetBodyIndices(model_id) # Put them in a randomly ordered line, for placing y_offset = (object_ordering[k] / float(total_num_objs) - 0.5) # RAnge -0.5 to 0.5 poses.append([ RollPitchYaw(np.random.uniform( 0., 2. * np.pi, size=3)).ToQuaternion().wxyz(), [-0.25, y_offset, 0.1] ]) k += 1 #$poses.append([ # RollPitchYaw(np.random.uniform(0., 2.*np.pi, size=3)).ToQuaternion().wxyz(), # [np.random.uniform(-0.2, 0.2), np.random.uniform(-0.1, 0.1), np.random.uniform(0.1, 0.3)]]) # Build a desk parser.AddModelFromFile(cupboard_model) mbp.WeldFrames(world_body.body_frame(), mbp.GetBodyByName("shelf_origin_body").body_frame(), RigidTransform(p=[0.0, 0, 0.0])) #parser.AddModelFromFile(dish_bin_model) #mbp.WeldFrames(world_body.body_frame(), mbp.GetBodyByName("bus_tub_01_decomp_body_link").body_frame(), # RigidTransform(p=[0.0, 0., 0.], rpy=RollPitchYaw(np.pi/2., 0., 0.))) mbp.AddForceElement(UniformGravityFieldElement()) mbp.Finalize() hydra_sg_spy = builder.AddSystem( HydraInteractionLeafSystem( mbp, scene_graph, all_manipulable_body_ids=all_manipulable_body_ids)) #builder.Connect(scene_graph.get_query_output_port(), # hydra_sg_spy.get_input_port(0)) builder.Connect(scene_graph.get_pose_bundle_output_port(), hydra_sg_spy.get_input_port(0)) builder.Connect(mbp.get_state_output_port(), hydra_sg_spy.get_input_port(1)) builder.Connect(hydra_sg_spy.get_output_port(0), mbp.get_applied_spatial_force_input_port()) visualizer = builder.AddSystem( MeshcatVisualizer(scene_graph, zmq_url="tcp://127.0.0.1:6000", draw_period=0.01)) builder.Connect(scene_graph.get_pose_bundle_output_port(), visualizer.get_input_port(0)) diagram = builder.Build() diagram_context = diagram.CreateDefaultContext() mbp_context = diagram.GetMutableSubsystemContext( mbp, diagram_context) sg_context = diagram.GetMutableSubsystemContext( scene_graph, diagram_context) q0 = mbp.GetPositions(mbp_context).copy() for k in range(len(poses)): offset = k * 7 q0[(offset):(offset + 4)] = poses[k][0] q0[(offset + 4):(offset + 7)] = poses[k][1] mbp.SetPositions(mbp_context, q0) simulator = Simulator(diagram, diagram_context) simulator.set_target_realtime_rate(1.0) simulator.set_publish_every_time_step(False) simulator.Initialize() ik = InverseKinematics(mbp, mbp_context) q_dec = ik.q() prog = ik.prog() def squaredNorm(x): return np.array([x[0]**2 + x[1]**2 + x[2]**2 + x[3]**2]) for k in range(len(poses)): # Quaternion norm prog.AddConstraint(squaredNorm, [1], [1], q_dec[(k * 7):(k * 7 + 4)]) # Trivial quaternion bounds prog.AddBoundingBoxConstraint(-np.ones(4), np.ones(4), q_dec[(k * 7):(k * 7 + 4)]) # Conservative bounds on on XYZ prog.AddBoundingBoxConstraint(np.array([-2., -2., -2.]), np.array([2., 2., 2.]), q_dec[(k * 7 + 4):(k * 7 + 7)]) def vis_callback(x): vis_diagram_context = diagram.CreateDefaultContext() mbp.SetPositions( diagram.GetMutableSubsystemContext(mbp, vis_diagram_context), x) pose_bundle = scene_graph.get_pose_bundle_output_port().Eval( diagram.GetMutableSubsystemContext(scene_graph, vis_diagram_context)) context = visualizer.CreateDefaultContext() context.FixInputPort(0, AbstractValue.Make(pose_bundle)) visualizer.Publish(context) prog.AddVisualizationCallback(vis_callback, q_dec) prog.AddQuadraticErrorCost(np.eye(q0.shape[0]) * 1.0, q0, q_dec) ik.AddMinimumDistanceConstraint(0.001, threshold_distance=1.0) prog.SetInitialGuess(q_dec, q0) print("Solving") # print "Initial guess: ", q0 start_time = time.time() solver = SnoptSolver() #solver = NloptSolver() sid = solver.solver_type() # SNOPT prog.SetSolverOption(sid, "Print file", "test.snopt") prog.SetSolverOption(sid, "Major feasibility tolerance", 1e-3) prog.SetSolverOption(sid, "Major optimality tolerance", 1e-2) prog.SetSolverOption(sid, "Minor feasibility tolerance", 1e-3) prog.SetSolverOption(sid, "Scale option", 0) #prog.SetSolverOption(sid, "Elastic weight", 1e1) #prog.SetSolverOption(sid, "Elastic mode", "Yes") # NLOPT #prog.SetSolverOption(sid, "initial_step", 0.1) #prog.SetSolverOption(sid, "xtol_rel", 1E-2) #prog.SetSolverOption(sid, "xtol_abs", 1E-2) #prog.SetSolverOption(sid, "Major step limit", 2) print("Solver opts: ", prog.GetSolverOptions(solver.solver_type())) result = mp.Solve(prog) print("Solve info: ", result) print("Solved in %f seconds" % (time.time() - start_time)) #print(IpoptSolver().Solve(prog)) print(result.get_solver_id().name()) q0_proj = result.GetSolution(q_dec) # print "Final: ", q0_proj mbp.SetPositions(mbp_context, q0_proj) simulator.StepTo(1000) raise StopIteration() except StopIteration: print(colored("Stopped, saving and restarting", 'yellow')) qf = mbp.GetPositions(mbp_context) # Decide whether to accept: all objs within bounds save = True for k in range(len(all_object_instances)): offset = k * 7 q = qf[offset:(offset + 7)] if q[4] <= -0.25 or q[4] >= 0.25 or q[5] <= -0.2 or q[ 5] >= 0.2 or q[6] <= -0.1: save = False break if save: print(colored("Saving", "green")) save_config(all_object_instances, qf, "mug_rack_environments_human.yaml") else: print( colored("Not saving due to bounds violation: " + str(q), "yellow")) except Exception as e: print(colored("Suffered other exception " + str(e), "red")) sys.exit(-1) except: print( colored("Suffered totally unknown exception! Probably sim.", "red"))
def test_warnings_and_errors(self): builder = DiagramBuilder() sg = builder.AddSystem(SceneGraph()) v2 = builder.AddSystem( MeshcatVisualizer(scene_graph=sg, zmq_url=ZMQ_URL, open_browser=False)) builder.Connect(sg.get_query_output_port(), v2.get_geometry_query_input_port()) v2.set_name("v2") v4 = builder.AddSystem( MeshcatVisualizer(scene_graph=None, zmq_url=ZMQ_URL, open_browser=False)) builder.Connect(sg.get_query_output_port(), v4.get_geometry_query_input_port()) v4.set_name("v4") v5 = ConnectMeshcatVisualizer(builder, scene_graph=sg, zmq_url=ZMQ_URL, open_browser=False) v5.set_name("v5") v7 = ConnectMeshcatVisualizer(builder, scene_graph=sg, output_port=sg.get_query_output_port(), zmq_url=ZMQ_URL, open_browser=False) v7.set_name("v7") with self.assertRaises(AssertionError): v8 = ConnectMeshcatVisualizer(builder, scene_graph=None, output_port=None, zmq_url=ZMQ_URL, open_browser=False) v8.set_name("v8") v10 = ConnectMeshcatVisualizer(builder, scene_graph=None, output_port=sg.get_query_output_port(), zmq_url=ZMQ_URL, open_browser=False) v10.set_name("v10") diagram = builder.Build() context = diagram.CreateDefaultContext() def PublishWithNoWarnings(v): with warnings.catch_warnings(record=True) as w: v.Publish(v.GetMyContextFromRoot(context)) self.assertEqual(len(w), 0, [x.message for x in w]) # Use geometry_query API v2.load(v2.GetMyContextFromRoot(context)) PublishWithNoWarnings(v2) v2.load() PublishWithNoWarnings(v2) # Use geometry_query API v4.load(v4.GetMyContextFromRoot(context)) PublishWithNoWarnings(v4) with self.assertRaises(RuntimeError): v4.load() # Can't work without scene_graph nor context. # Use geometry_query API v5.load(v5.GetMyContextFromRoot(context)) PublishWithNoWarnings(v5) v5.load() PublishWithNoWarnings(v5) # Use geometry_query API v7.load(v7.GetMyContextFromRoot(context)) PublishWithNoWarnings(v7) v7.load() PublishWithNoWarnings(v7) # Use geometry_query API v10.load(v10.GetMyContextFromRoot(context)) PublishWithNoWarnings(v10) with self.assertRaises(RuntimeError): v10.load() # Can't work without scene_graph nor context.
def test_lcm_driven_loop(self): """Duplicates the test logic in `lcm_driven_loop_test.cc`.""" lcm_url = "udpm://239.255.76.67:7669" t_start = 3. t_end = 10. def publish_loop(): # Publishes a set of messages for the driven loop. This should be # run from a separate process. # N.B. Because of this, care should be taken not to share C++ # objects between process boundaries. t = t_start while t <= t_end: message = header_t() message.utime = int(1e6 * t) lcm.Publish("TEST_LOOP", message.encode()) time.sleep(0.1) t += 1 class DummySys(LeafSystem): # Converts message to time in seconds. def __init__(self): LeafSystem.__init__(self) self._DeclareAbstractInputPort("header_t", AbstractValue.Make(header_t)) self._DeclareVectorOutputPort(BasicVector(1), self._calc_output) def _calc_output(self, context, output): message = self.EvalAbstractInput(context, 0).get_value() y = output.get_mutable_value() y[:] = message.utime / 1e6 # Construct diagram for LcmDrivenLoop. lcm = DrakeLcm(lcm_url) utime = mut.PyUtimeMessageToSeconds(header_t) sub = mut.LcmSubscriberSystem.Make("TEST_LOOP", header_t, lcm) builder = DiagramBuilder() builder.AddSystem(sub) dummy = builder.AddSystem(DummySys()) builder.Connect(sub.get_output_port(0), dummy.get_input_port(0)) logger = LogOutput(dummy.get_output_port(0), builder) logger.set_forced_publish_only() diagram = builder.Build() dut = mut.LcmDrivenLoop(diagram, sub, None, lcm, utime) dut.set_publish_on_every_received_message(True) # N.B. Use `multiprocessing` instead of `threading` so that we may # avoid issues with GIL deadlocks. publish_proc = Process(target=publish_loop) publish_proc.start() # Initialize to first message. first_msg = dut.WaitForMessage() dut.get_mutable_context().set_time(utime.GetTimeInSeconds(first_msg)) # Run to desired amount. (Anything more will cause interpreter to # "freeze".) dut.RunToSecondsAssumingInitialized(t_end) publish_proc.join() # Check expected values. log_t_expected = np.array([4, 5, 6, 7, 8, 9]) log_t = logger.sample_times() self.assertTrue(np.allclose(log_t_expected, log_t)) log_y = logger.data() self.assertTrue(np.allclose(log_t_expected, log_y))
def test_contact_force(self): """A block sitting on a table.""" object_file_path = FindResourceOrThrow( "drake/examples/manipulation_station/models/061_foam_brick.sdf") table_file_path = FindResourceOrThrow( "drake/examples/kuka_iiwa_arm/models/table/" "extra_heavy_duty_table_surface_only_collision.sdf") # T: tabletop frame. X_TObject = RigidTransform([0, 0, 0.2]) builder = DiagramBuilder() plant = MultibodyPlant(0.002) _, scene_graph = AddMultibodyPlantSceneGraph(builder, plant) object_model = Parser(plant=plant).AddModelFromFile(object_file_path) table_model = Parser(plant=plant).AddModelFromFile(table_file_path) # Weld table to world. plant.WeldFrames(A=plant.world_frame(), B=plant.GetFrameByName("link", table_model)) plant.Finalize() # Add meshcat visualizer. viz = builder.AddSystem( MeshcatVisualizer(scene_graph, zmq_url=ZMQ_URL, open_browser=False)) builder.Connect(scene_graph.get_pose_bundle_output_port(), viz.get_input_port(0)) # Add contact visualizer. contact_viz = builder.AddSystem( MeshcatContactVisualizer(meshcat_viz=viz, force_threshold=0, contact_force_scale=10, plant=plant)) contact_input_port = contact_viz.GetInputPort("contact_results") builder.Connect(plant.GetOutputPort("contact_results"), contact_input_port) builder.Connect(scene_graph.get_pose_bundle_output_port(), contact_viz.GetInputPort("pose_bundle")) diagram = builder.Build() diagram_context = diagram.CreateDefaultContext() mbp_context = diagram.GetMutableSubsystemContext( plant, diagram_context) X_WT = plant.CalcRelativeTransform(mbp_context, plant.world_frame(), plant.GetFrameByName("top_center")) plant.SetFreeBodyPose(mbp_context, plant.GetBodyByName("base_link", object_model), X_WT.multiply(X_TObject)) simulator = Simulator(diagram, diagram_context) simulator.set_publish_every_time_step(False) simulator.AdvanceTo(1.0) contact_viz_context = (diagram.GetMutableSubsystemContext( contact_viz, diagram_context)) contact_results = contact_viz.EvalAbstractInput( contact_viz_context, contact_input_port.get_index()).get_value() self.assertGreater(contact_results.num_point_pair_contacts(), 0) self.assertEqual(contact_viz._contact_key_counter, 4)
def main(): parser = argparse.ArgumentParser(description=__doc__) parser.add_argument( "--num_samples", type=int, default=50, help="Number of Monte Carlo samples to use to estimate performance.") parser.add_argument("--torque_limit", type=float, default=2.0, help="Torque limit of the pendulum.") args = parser.parse_args() if args.torque_limit < 0: raise InvalidArgumentError("Please supply a nonnegative torque limit.") # Assemble the Pendulum plant. builder = DiagramBuilder() pendulum = builder.AddSystem(MultibodyPlant()) file_name = FindResourceOrThrow("drake/examples/pendulum/Pendulum.urdf") Parser(pendulum).AddModelFromFile(file_name) pendulum.WeldFrames(pendulum.world_frame(), pendulum.GetFrameByName("base")) pendulum.Finalize() # Set the pendulum to start at uniformly random # positions (but always zero velocity). elbow = pendulum.GetMutableJointByName("theta") upright_theta = np.pi theta_expression = Variable(name="theta", type=Variable.Type.RANDOM_UNIFORM) * 2. * np.pi elbow.set_random_angle_distribution(theta_expression) # Set up LQR, with high position gains to try to ensure the # ROA is close to the theoretical torque-limited limit. Q = np.diag([100., 1.]) R = np.identity(1) * 0.01 linearize_context = pendulum.CreateDefaultContext() linearize_context.SetContinuousState(np.array([upright_theta, 0.])) actuation_port_index = pendulum.get_actuation_input_port().get_index() linearize_context.FixInputPort(actuation_port_index, np.zeros(1)) controller = builder.AddSystem( LinearQuadraticRegulator(pendulum, linearize_context, Q, R, np.zeros(0), actuation_port_index)) # Apply the torque limit. torque_limit = args.torque_limit torque_limiter = builder.AddSystem( Saturation(min_value=np.array([-torque_limit]), max_value=np.array([torque_limit]))) builder.Connect(controller.get_output_port(0), torque_limiter.get_input_port(0)) builder.Connect(torque_limiter.get_output_port(0), pendulum.get_actuation_input_port()) builder.Connect(pendulum.get_output_port(0), controller.get_input_port(0)) diagram = builder.Build() # Perform the Monte Carlo simulation. def make_simulator(generator): ''' Create a simulator for the system using the given generator. ''' simulator = Simulator(diagram) simulator.set_target_realtime_rate(0) simulator.Initialize() return simulator def calc_wrapped_error(system, context): ''' Given a context from the end of the simulation, calculate an error -- which for this stabilizing task is the distance from the fixed point. ''' state = diagram.GetSubsystemContext( pendulum, context).get_continuous_state_vector() error = state.GetAtIndex(0) - upright_theta # Wrap error to [-pi, pi]. return (error + np.pi) % (2 * np.pi) - np.pi num_samples = args.num_samples results = MonteCarloSimulation(make_simulator=make_simulator, output=calc_wrapped_error, final_time=1.0, num_samples=num_samples, generator=RandomGenerator()) # Compute results. # The "success" region is fairly large since some "stabilized" trials # may still be oscillating around the fixed point. Failed examples are # consistently much farther from the fixed point than this. binary_results = np.array([abs(res.output) < 0.1 for res in results]) passing_ratio = float(sum(binary_results)) / len(results) # 95% confidence interval for the passing ratio. passing_ratio_var = 1.96 * np.sqrt(passing_ratio * (1. - passing_ratio) / len(results)) print("Monte-Carlo estimated performance across %d samples: " "%.2f%% +/- %0.2f%%" % (num_samples, passing_ratio * 100, passing_ratio_var * 100)) # Analytically compute the best possible ROA, for comparison, but # calculating where the torque needed to lift the pendulum exceeds # the torque limit. arm_radius = 0.5 arm_mass = 1.0 # torque = r x f = r * (m * 9.81 * sin(theta)) # theta = asin(torque / (r * m)) if torque_limit <= (arm_radius * arm_mass * 9.81): roa_half_width = np.arcsin(torque_limit / (arm_radius * arm_mass * 9.81)) else: roa_half_width = np.pi roa_as_fraction_of_state_space = roa_half_width / np.pi print("Max possible ROA = %0.2f%% of state space, which should" " match with the above estimate." % (100 * roa_as_fraction_of_state_space))
def main(): parser = argparse.ArgumentParser( description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) parser.add_argument( "filename", type=str, help="Path to an SDF or URDF file.") position_group = parser.add_mutually_exclusive_group() position_group.add_argument( "--position", type=float, nargs="+", default=[], help="A list of positions which must be the same length as the number " "of positions in the sdf model. Note that most models have a " "floating-base joint by default (unless the sdf explicitly welds " "the base to the world, and so have 7 positions corresponding to " "the quaternion representation of that floating-base position.") position_group.add_argument( "--joint_position", type=float, nargs="+", default=[], help="A list of positions which must be the same length as the number " "of positions ASSOCIATED WITH JOINTS in the sdf model. This " "does not include, e.g., floating-base coordinates, which will " "be assigned a default value.") parser.add_argument( "--test", action='store_true', help="Disable opening the gui window for testing.") # TODO(russt): Add option to weld the base to the world pending the # availability of GetUniqueBaseBody requested in #9747. args = parser.parse_args() filename = args.filename if not os.path.isfile(filename): parser.error("File does not exist: {}".format(filename)) builder = DiagramBuilder() scene_graph = builder.AddSystem(SceneGraph()) # Construct a MultibodyPlant and load the SDF into it. plant = MultibodyPlant() plant.RegisterAsSourceForSceneGraph(scene_graph) Parser(plant).AddModelFromFile(filename) plant.Finalize(scene_graph) # Add sliders to set positions of the joints. sliders = builder.AddSystem(JointSliders(robot=plant)) to_pose = builder.AddSystem(MultibodyPositionToGeometryPose(plant)) builder.Connect(sliders.get_output_port(0), to_pose.get_input_port()) builder.Connect( to_pose.get_output_port(), scene_graph.get_source_pose_port(plant.get_source_id())) # Connect this to drake_visualizer. ConnectDrakeVisualizer(builder=builder, scene_graph=scene_graph) if len(args.position): sliders.set_position(args.position) elif len(args.joint_position): sliders.set_joint_position(args.joint_position) # Make the diagram and run it. diagram = builder.Build() simulator = Simulator(diagram) simulator.set_publish_every_time_step(False) if args.test: sliders.window.withdraw() simulator.StepTo(0.1) else: simulator.set_target_realtime_rate(1.0) simulator.StepTo(np.inf)
def test_diagram_simulation(self): # TODO(eric.cousineau): Move this to `analysis_test.py`. # Similar to: //systems/framework:diagram_test, ExampleDiagram size = 3 builder = DiagramBuilder() self.assertTrue(builder.empty()) adder0 = builder.AddSystem(Adder(2, size)) adder0.set_name("adder0") self.assertFalse(builder.empty()) adder1 = builder.AddSystem(Adder(2, size)) adder1.set_name("adder1") integrator = builder.AddSystem(Integrator(size)) integrator.set_name("integrator") self.assertEqual( builder.GetSystems(), [adder0, adder1, integrator]) self.assertEqual( builder.GetMutableSystems(), [adder0, adder1, integrator]) builder.Connect(adder0.get_output_port(0), adder1.get_input_port(0)) builder.Connect(adder1.get_output_port(0), integrator.get_input_port(0)) # Exercise naming variants. builder.ExportInput(adder0.get_input_port(0)) builder.ExportInput(adder0.get_input_port(1), kUseDefaultName) builder.ExportInput(adder1.get_input_port(1), "third_input") builder.ExportOutput(integrator.get_output_port(0), "result") diagram = builder.Build() self.assertEqual(adder0.get_name(), "adder0") self.assertEqual(diagram.GetSubsystemByName("adder0"), adder0) self.assertEqual( diagram.GetSystems(), [adder0, adder1, integrator]) # TODO(eric.cousineau): Figure out unicode handling if needed. # See //systems/framework/test/diagram_test.cc:349 (sha: bc84e73) # for an example name. diagram.set_name("test_diagram") simulator = Simulator(diagram) context = simulator.get_mutable_context() # Create and attach inputs. # TODO(eric.cousineau): Not seeing any assertions being printed if no # inputs are connected. Need to check this behavior. input0 = np.array([0.1, 0.2, 0.3]) diagram.get_input_port(0).FixValue(context, input0) input1 = np.array([0.02, 0.03, 0.04]) diagram.get_input_port(1).FixValue(context, input1) # Test the BasicVector overload. input2 = BasicVector([0.003, 0.004, 0.005]) diagram.get_input_port(2).FixValue(context, input2) # Initialize integrator states. integrator_xc = ( diagram.GetMutableSubsystemState(integrator, context) .get_mutable_continuous_state().get_vector()) integrator_xc.SetFromVector([0, 1, 2]) simulator.Initialize() # Simulate briefly, and take full-context snapshots at intermediate # points. n = 6 times = np.linspace(0, 1, n) context_log = [] for t in times: simulator.AdvanceTo(t) # Record snapshot of *entire* context. context_log.append(context.Clone()) # Test binding for PrintSimulatorStatistics PrintSimulatorStatistics(simulator) xc_initial = np.array([0, 1, 2]) xc_final = np.array([0.123, 1.234, 2.345]) for i, context_i in enumerate(context_log): t = times[i] self.assertEqual(context_i.get_time(), t) xc = context_i.get_continuous_state_vector().CopyToVector() xc_expected = (float(i) / (n - 1) * (xc_final - xc_initial) + xc_initial) self.assertTrue(np.allclose(xc, xc_expected))
def RunRealRobot(self, plans_list, gripper_setpoint_list): ''' Constructs a Diagram that sends commands to ManipulationStationHardwareInterface. :param plans_list: :param gripper_setpoint_list: :param extra_time: :param real_time_rate: :param q0_kuka: :return: ''' builder = DiagramBuilder() camera_ids = ["805212060544"] station_hardware = ManipulationStationHardwareInterface(camera_ids) station_hardware.Connect(wait_for_cameras=False) builder.AddSystem(station_hardware) # Add plan runner # Add plan runner. plan_runner = ManipStationPlanRunner( station=self.station, kuka_plans=plans_list, gripper_setpoint_list=gripper_setpoint_list) builder.AddSystem(plan_runner) builder.Connect(plan_runner.hand_setpoint_output_port, station_hardware.GetInputPort("wsg_position")) builder.Connect(plan_runner.gripper_force_limit_output_port, station_hardware.GetInputPort("wsg_force_limit")) demux = builder.AddSystem(Demultiplexer(14, 7)) builder.Connect( plan_runner.GetOutputPort("iiwa_position_and_torque_command"), demux.get_input_port(0)) builder.Connect(demux.get_output_port(0), station_hardware.GetInputPort("iiwa_position")) builder.Connect( demux.get_output_port(1), station_hardware.GetInputPort("iiwa_feedforward_torque")) builder.Connect( station_hardware.GetOutputPort("iiwa_position_measured"), plan_runner.iiwa_position_input_port) builder.Connect( station_hardware.GetOutputPort("iiwa_velocity_estimated"), plan_runner.iiwa_velocity_input_port) # Add logger iiwa_position_measured_log = LogOutput( station_hardware.GetOutputPort("iiwa_position_measured"), builder) iiwa_position_measured_log._DeclarePeriodicPublish(0.005) iiwa_external_torque_log = LogOutput( station_hardware.GetOutputPort("iiwa_torque_external"), builder) iiwa_external_torque_log._DeclarePeriodicPublish(0.005) wsg_state_log = LogOutput( station_hardware.GetOutputPort("wsg_state_measured"), builder) wsg_state_log._DecalrePeriodicPublish(0.1) wsg_command_log = LogOutput(plan_runner.hand_setpoint_output_port, builder) wsg_command_log._DeclarePeriodicPublish(0.1) # build diagram diagram = builder.Build() RenderSystemWithGraphviz(diagram) # construct simulator simulator = Simulator(diagram) simulator.set_target_realtime_rate(1.0) simulator.set_publish_every_time_step(False) sim_duration = 0. for plan in plans_list: sim_duration += plan.get_duration() * 1.1 print "sending trajectories in 2 seconds..." time.sleep(1.0) print "sending trajectories in 1 second..." time.sleep(1.0) print "sending trajectories now!" simulator.StepTo(sim_duration) return iiwa_position_measured_log, iiwa_external_torque_log, wsg_state_log, wsg_command_log
def main(): parser = argparse.ArgumentParser(description=__doc__) parser.add_argument( "--target_realtime_rate", type=float, default=1.0, help="Desired rate relative to real time. See documentation for " "Simulator::set_target_realtime_rate() for details.") parser.add_argument( "--duration", type=float, default=np.inf, help="Desired duration of the simulation in seconds.") parser.add_argument( "--hardware", action='store_true', help="Use the ManipulationStationHardwareInterface instead of an " "in-process simulation.") parser.add_argument( "--test", action='store_true', help="Disable opening the gui window for testing.") parser.add_argument( '--setup', type=str, default='manipulation_class', help="The manipulation station setup to simulate. ", choices=['manipulation_class', 'clutter_clearing', 'planar']) MeshcatVisualizer.add_argparse_argument(parser) args = parser.parse_args() builder = DiagramBuilder() if args.hardware: # TODO(russt): Replace this hard-coded camera serial number with a # config file. camera_ids = ["805212060544"] station = builder.AddSystem(ManipulationStationHardwareInterface( camera_ids)) station.Connect(wait_for_cameras=False) else: station = builder.AddSystem(ManipulationStation()) # Initializes the chosen station type. if args.setup == 'manipulation_class': station.SetupManipulationClassStation() station.AddManipulandFromFile( "drake/examples/manipulation_station/models/" + "061_foam_brick.sdf", RigidTransform(RotationMatrix.Identity(), [0.6, 0, 0])) elif args.setup == 'clutter_clearing': station.SetupClutterClearingStation() ycb_objects = CreateClutterClearingYcbObjectList() for model_file, X_WObject in ycb_objects: station.AddManipulandFromFile(model_file, X_WObject) elif args.setup == 'planar': station.SetupPlanarIiwaStation() station.AddManipulandFromFile( "drake/examples/manipulation_station/models/" + "061_foam_brick.sdf", RigidTransform(RotationMatrix.Identity(), [0.6, 0, 0])) station.Finalize() ConnectDrakeVisualizer(builder, station.get_scene_graph(), station.GetOutputPort("pose_bundle")) if args.meshcat: meshcat = builder.AddSystem(MeshcatVisualizer( station.get_scene_graph(), zmq_url=args.meshcat, open_browser=args.open_browser)) builder.Connect(station.GetOutputPort("pose_bundle"), meshcat.get_input_port(0)) if args.setup == 'planar': meshcat.set_planar_viewpoint() if args.setup == 'planar': pyplot_visualizer = builder.AddSystem(PlanarSceneGraphVisualizer( station.get_scene_graph())) builder.Connect(station.GetOutputPort("pose_bundle"), pyplot_visualizer.get_input_port(0)) teleop = builder.AddSystem(JointSliders(station.get_controller_plant(), length=800)) if args.test: teleop.window.withdraw() # Don't display the window when testing. num_iiwa_joints = station.num_iiwa_joints() filter = builder.AddSystem(FirstOrderLowPassFilter( time_constant=2.0, size=num_iiwa_joints)) builder.Connect(teleop.get_output_port(0), filter.get_input_port(0)) builder.Connect(filter.get_output_port(0), station.GetInputPort("iiwa_position")) wsg_buttons = builder.AddSystem(SchunkWsgButtons(teleop.window)) builder.Connect(wsg_buttons.GetOutputPort("position"), station.GetInputPort("wsg_position")) builder.Connect(wsg_buttons.GetOutputPort("force_limit"), station.GetInputPort("wsg_force_limit")) # When in regression test mode, log our joint velocities to later check # that they were sufficiently quiet. if args.test: iiwa_velocities = builder.AddSystem(SignalLogger(num_iiwa_joints)) builder.Connect(station.GetOutputPort("iiwa_velocity_estimated"), iiwa_velocities.get_input_port(0)) else: iiwa_velocities = None diagram = builder.Build() simulator = Simulator(diagram) # This is important to avoid duplicate publishes to the hardware interface: simulator.set_publish_every_time_step(False) station_context = diagram.GetMutableSubsystemContext( station, simulator.get_mutable_context()) station.GetInputPort("iiwa_feedforward_torque").FixValue( station_context, np.zeros(num_iiwa_joints)) # If the diagram is only the hardware interface, then we must advance it a # little bit so that first LCM messages get processed. A simulated plant is # already publishing correct positions even without advancing, and indeed # we must not advance a simulated plant until the sliders and filters have # been initialized to match the plant. if args.hardware: simulator.AdvanceTo(1e-6) # Eval the output port once to read the initial positions of the IIWA. q0 = station.GetOutputPort("iiwa_position_measured").Eval( station_context) teleop.set_position(q0) filter.set_initial_output_value(diagram.GetMutableSubsystemContext( filter, simulator.get_mutable_context()), q0) simulator.set_target_realtime_rate(args.target_realtime_rate) simulator.AdvanceTo(args.duration) # Ensure that our initialization logic was correct, by inspecting our # logged joint velocities. if args.test: for time, qdot in zip(iiwa_velocities.sample_times(), iiwa_velocities.data().transpose()): # TODO(jwnimmer-tri) We should be able to do better than a 40 # rad/sec limit, but that's the best we can enforce for now. if qdot.max() > 0.1: print(f"ERROR: large qdot {qdot} at time {time}") sys.exit(1)
def RunSimulation(self, plans_list, gripper_setpoint_list, extra_time=0, real_time_rate=1.0, q0_kuka=np.zeros(7)): ''' Constructs a Diagram that sends commands to ManipulationStation. :param plans_list: :param gripper_setpoint_list: :param extra_time: :param real_time_rate: :param q0_kuka: :return: ''' builder = DiagramBuilder() builder.AddSystem(self.station) # Add plan runner. plan_runner = ManipStationPlanRunner( station=self.station, kuka_plans=plans_list, gripper_setpoint_list=gripper_setpoint_list) builder.AddSystem(plan_runner) builder.Connect(plan_runner.hand_setpoint_output_port, self.station.GetInputPort("wsg_position")) builder.Connect(plan_runner.gripper_force_limit_output_port, self.station.GetInputPort("wsg_force_limit")) demux = builder.AddSystem(Demultiplexer(14, 7)) builder.Connect( plan_runner.GetOutputPort("iiwa_position_and_torque_command"), demux.get_input_port(0)) builder.Connect(demux.get_output_port(0), self.station.GetInputPort("iiwa_position")) builder.Connect(demux.get_output_port(1), self.station.GetInputPort("iiwa_feedforward_torque")) builder.Connect(self.station.GetOutputPort("iiwa_position_measured"), plan_runner.iiwa_position_input_port) builder.Connect(self.station.GetOutputPort("iiwa_velocity_estimated"), plan_runner.iiwa_velocity_input_port) # Add meshcat visualizer scene_graph = self.station.get_mutable_scene_graph() viz = MeshcatVisualizer(scene_graph, is_drawing_contact_force=True, plant=self.plant) self.viz = viz builder.AddSystem(viz) builder.Connect(self.station.GetOutputPort("pose_bundle"), viz.GetInputPort("lcm_visualization")) builder.Connect(self.station.GetOutputPort("contact_results"), viz.GetInputPort("contact_results")) # Add logger iiwa_position_command_log = LogOutput(demux.get_output_port(0), builder) iiwa_position_command_log._DeclarePeriodicPublish(0.005) iiwa_external_torque_log = LogOutput( self.station.GetOutputPort("iiwa_torque_external"), builder) iiwa_external_torque_log._DeclarePeriodicPublish(0.005) iiwa_position_measured_log = LogOutput( self.station.GetOutputPort("iiwa_position_measured"), builder) iiwa_position_measured_log._DeclarePeriodicPublish(0.005) wsg_state_log = LogOutput( self.station.GetOutputPort("wsg_state_measured"), builder) wsg_state_log._DeclarePeriodicPublish(0.1) wsg_command_log = LogOutput(plan_runner.hand_setpoint_output_port, builder) wsg_command_log._DeclarePeriodicPublish(0.1) # build diagram diagram = builder.Build() viz.load() time.sleep(2.0) RenderSystemWithGraphviz(diagram) # construct simulator simulator = Simulator(diagram) context = diagram.GetMutableSubsystemContext( self.station, simulator.get_mutable_context()) # set initial state of the robot self.station.SetIiwaPosition(q0_kuka, context) self.station.SetIiwaVelocity(np.zeros(7), context) self.station.SetWsgPosition(0.05, context) self.station.SetWsgVelocity(0, context) # set initial hinge angles of the cupboard. # setting hinge angle to exactly 0 or 90 degrees will result in intermittent contact # with small contact forces between the door and the cupboard body. left_hinge_joint = self.plant.GetJointByName("left_door_hinge") left_hinge_joint.set_angle( context=self.station.GetMutableSubsystemContext( self.plant, context), angle=-0.001) right_hinge_joint = self.plant.GetJointByName("right_door_hinge") right_hinge_joint.set_angle( context=self.station.GetMutableSubsystemContext( self.plant, context), angle=0.001) # set initial pose of the object self.plant.tree().SetFreeBodyPoseOrThrow( self.plant.GetBodyByName(self.object_base_link_name, self.object), self.X_WObject, self.station.GetMutableSubsystemContext(self.plant, context)) simulator.set_publish_every_time_step(False) simulator.set_target_realtime_rate(real_time_rate) simulator.Initialize() sim_duration = 0. for plan in plans_list: sim_duration += plan.get_duration() * 1.1 sim_duration += extra_time print "simulation duration", sim_duration simulator.StepTo(sim_duration) return iiwa_position_command_log, \ iiwa_position_measured_log, \ iiwa_external_torque_log, \ wsg_state_log, \ wsg_command_log
def RunSimulation(self, plan_list, gripper_setpoint_list, extra_time=0, real_time_rate=1.0, q0_kuka=np.zeros(7), is_visualizing=True, sim_duration=None, is_plan_runner_diagram=False): """ Constructs a Diagram that sends commands to ManipulationStation. @param plan_list: A list of Plans to be executed. @param gripper_setpoint_list: A list of gripper setpoints. Each setpoint corresponds to a Plan. @param extra_time: the amount of time for which commands are sent, in addition to the sum of the durations of all plans. @param real_time_rate: 1.0 means realtime; 0 means as fast as possible. @param q0_kuka: initial configuration of the robot. @param is_visualizing: if true, adds MeshcatVisualizer to the Diagram. It should be set to False when running tests. @param sim_duration: the duration of simulation in seconds. If unset, it is set to the sum of the durations of all plans in plan_list plus extra_time. @param is_plan_runner_diagram: True: use the diagram version of PlanRunner; False: use the leaf version of PlanRunner. @return: logs of robot configuration and MultibodyPlant, generated by simulation. Logs are SignalLogger systems, whose data can be accessed by SignalLogger.data(). """ builder = DiagramBuilder() builder.AddSystem(self.station) # Add plan runner. if is_plan_runner_diagram: plan_runner = CreateManipStationPlanRunnerDiagram( station=self.station, kuka_plans=plan_list, gripper_setpoint_list=gripper_setpoint_list) else: plan_runner = ManipStationPlanRunner( station=self.station, kuka_plans=plan_list, gripper_setpoint_list=gripper_setpoint_list) self.plan_runner = plan_runner builder.AddSystem(plan_runner) builder.Connect(plan_runner.GetOutputPort("gripper_setpoint"), self.station.GetInputPort("wsg_position")) builder.Connect(plan_runner.GetOutputPort("force_limit"), self.station.GetInputPort("wsg_force_limit")) demux = builder.AddSystem(Demultiplexer(14, 7)) builder.Connect( plan_runner.GetOutputPort("iiwa_position_and_torque_command"), demux.get_input_port(0)) builder.Connect(demux.get_output_port(0), self.station.GetInputPort("iiwa_position")) builder.Connect(demux.get_output_port(1), self.station.GetInputPort("iiwa_feedforward_torque")) builder.Connect(self.station.GetOutputPort("iiwa_position_measured"), plan_runner.GetInputPort("iiwa_position")) builder.Connect(self.station.GetOutputPort("iiwa_velocity_estimated"), plan_runner.GetInputPort("iiwa_velocity")) # Add meshcat visualizer if is_visualizing: scene_graph = self.station.get_mutable_scene_graph() viz = MeshcatVisualizer(scene_graph, is_drawing_contact_force = False, plant = self.plant) builder.AddSystem(viz) builder.Connect(self.station.GetOutputPort("pose_bundle"), viz.GetInputPort("lcm_visualization")) builder.Connect(self.station.GetOutputPort("contact_results"), viz.GetInputPort("contact_results")) # Add logger iiwa_position_command_log = LogOutput(demux.get_output_port(0), builder) iiwa_position_command_log._DeclarePeriodicPublish(0.005) iiwa_external_torque_log = LogOutput( self.station.GetOutputPort("iiwa_torque_external"), builder) iiwa_external_torque_log._DeclarePeriodicPublish(0.005) iiwa_position_measured_log = LogOutput( self.station.GetOutputPort("iiwa_position_measured"), builder) iiwa_position_measured_log._DeclarePeriodicPublish(0.005) plant_state_log = LogOutput( self.station.GetOutputPort("plant_continuous_state"), builder) plant_state_log._DeclarePeriodicPublish(0.005) # build diagram diagram = builder.Build() if is_visualizing: viz.load() time.sleep(2.0) # RenderSystemWithGraphviz(diagram) # construct simulator simulator = Simulator(diagram) self.simulator = simulator context = diagram.GetMutableSubsystemContext( self.station, simulator.get_mutable_context()) # set initial state of the robot self.station.SetIiwaPosition(q0_kuka, context) self.station.SetIiwaVelocity(np.zeros(7), context) self.station.SetWsgPosition(0.05, context) self.station.SetWsgVelocity(0, context) # set initial hinge angles of the cupboard. # setting hinge angle to exactly 0 or 90 degrees will result in intermittent contact # with small contact forces between the door and the cupboard body. left_hinge_joint = self.plant.GetJointByName("left_door_hinge") left_hinge_joint.set_angle( context=self.station.GetMutableSubsystemContext(self.plant, context), angle=-np.pi/2+0.001) right_hinge_joint = self.plant.GetJointByName("right_door_hinge") right_hinge_joint.set_angle( context=self.station.GetMutableSubsystemContext(self.plant, context), angle=np.pi/2-0.001) # set initial pose of the object if self.object_base_link_name is not None: self.plant.tree().SetFreeBodyPoseOrThrow( self.plant.GetBodyByName(self.object_base_link_name, self.object), self.X_WObject, self.station.GetMutableSubsystemContext(self.plant, context)) simulator.set_publish_every_time_step(False) simulator.set_target_realtime_rate(real_time_rate) # calculate starting time for all plans. t_plan = GetPlanStartingTimes(plan_list) if sim_duration is None: sim_duration = t_plan[-1] + extra_time print "simulation duration", sim_duration simulator.Initialize() simulator.StepTo(sim_duration) return iiwa_position_command_log, iiwa_position_measured_log, \ iiwa_external_torque_log, plant_state_log
def test_composition_gripper_workflow(self): """Tests subgraphs (pre-finalize) for composition, with a scene graph, welding bodies together across different subgraphs.""" # Create IIWA. iiwa_builder = DiagramBuilder() iiwa_plant, iiwa_scene_graph = AddMultibodyPlantSceneGraph( iiwa_builder, time_step=0.) iiwa_file = FindResourceOrThrow( "drake/manipulation/models/iiwa_description/urdf/" "iiwa14_spheres_dense_elbow_collision.urdf") iiwa_model = Parser(iiwa_plant).AddModelFromFile(iiwa_file, "iiwa") iiwa_plant.WeldFrames(iiwa_plant.world_frame(), iiwa_plant.GetFrameByName("base")) iiwa_subgraph = mut.MultibodyPlantSubgraph( mut.get_elements_from_plant(iiwa_plant, iiwa_scene_graph)) self.assertIsInstance(iiwa_subgraph, mut.MultibodyPlantSubgraph) mut.disconnect_subgraph_from_world(iiwa_subgraph) # Create WSG. wsg_builder = DiagramBuilder() wsg_plant, wsg_scene_graph = AddMultibodyPlantSceneGraph(wsg_builder, time_step=0.) wsg_file = FindResourceOrThrow( "drake/manipulation/models/wsg_50_description/sdf/" "schunk_wsg_50.sdf") wsg_model = Parser(wsg_plant).AddModelFromFile(wsg_file, "gripper_model") wsg_plant.WeldFrames(wsg_plant.world_frame(), wsg_plant.GetFrameByName("__model__")) wsg_subgraph = mut.MultibodyPlantSubgraph( mut.get_elements_from_plant(wsg_plant, wsg_scene_graph)) self.assertIsInstance(wsg_subgraph, mut.MultibodyPlantSubgraph) mut.disconnect_subgraph_from_world(wsg_subgraph) builder = DiagramBuilder() plant, scene_graph = AddMultibodyPlantSceneGraph(builder, time_step=1e-3) iiwa_to_plant = iiwa_subgraph.add_to(plant, scene_graph) self.assertIsInstance(iiwa_to_plant, mut.MultibodyPlantElementsMap) wsg_to_plant = wsg_subgraph.add_to(plant, scene_graph) self.assertIsInstance(wsg_to_plant, mut.MultibodyPlantElementsMap) if VISUALIZE: print("test_composition") ConnectDrakeVisualizer(iiwa_builder, iiwa_scene_graph) ConnectDrakeVisualizer(wsg_builder, wsg_scene_graph) ConnectDrakeVisualizer(builder, scene_graph) rpy_deg = np.array([90., 0., 90]) X_7G = RigidTransform(p=[0, 0, 0.114], rpy=RollPitchYaw(rpy_deg * np.pi / 180)) frame_7 = plant.GetFrameByName("iiwa_link_7") frame_G = plant.GetFrameByName("body") plant.WeldFrames(frame_7, frame_G, X_7G) plant.Finalize() q_iiwa = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7] q_wsg = [-0.03, 0.03] iiwa_plant.Finalize() iiwa_diagram = iiwa_builder.Build() iiwa_d_context = iiwa_diagram.CreateDefaultContext() iiwa_context = iiwa_plant.GetMyContextFromRoot(iiwa_d_context) iiwa_plant.SetPositions(iiwa_context, iiwa_model, q_iiwa) wsg_plant.Finalize() wsg_diagram = wsg_builder.Build() wsg_d_context = wsg_diagram.CreateDefaultContext() wsg_context = wsg_plant.GetMyContextFromRoot(wsg_d_context) wsg_plant.SetPositions(wsg_context, wsg_model, q_wsg) # Transfer state and briefly compare. diagram = builder.Build() d_context = diagram.CreateDefaultContext() context = plant.GetMyContextFromRoot(d_context) iiwa_to_plant.copy_state(iiwa_context, context) wsg_to_plant.copy_state(wsg_context, context) # Compare frames from sub-plants. util.compare_frames(plant, context, iiwa_plant, iiwa_context, "base", "iiwa_link_7") util.compare_frames(plant, context, wsg_plant, wsg_context, "body", "left_finger") # Visualize. if VISUALIZE: print(" Visualize IIWA") Simulator(iiwa_diagram, iiwa_d_context.Clone()).Initialize() input(" Press enter...") print(" Visualize WSG") Simulator(wsg_diagram, wsg_d_context.Clone()).Initialize() input(" Press enter...") print(" Visualize Composite") Simulator(diagram, d_context.Clone()).Initialize() input(" Press enter...") self.do_exploding_iiwa_sim(plant, scene_graph, context)