コード例 #1
0
    def load(self):
        """
        Loads ``meshcat`` visualization elements.

        Precondition:
            The ``scene_graph`` used to construct this object must be part of a
            fully constructed diagram (e.g. via ``DiagramBuilder.Build()``).
        """
        self.vis[self.prefix].delete()

        # Intercept load message via mock LCM.
        mock_lcm = DrakeMockLcm()
        DispatchLoadMessage(self._scene_graph, mock_lcm)
        load_robot_msg = lcmt_viewer_load_robot.decode(
            mock_lcm.get_last_published_message("DRAKE_VIEWER_LOAD_ROBOT"))
        # Translate elements to `meshcat`.
        for i in range(load_robot_msg.num_links):
            link = load_robot_msg.link[i]
            [source_name, frame_name] = self._parse_name(link.name)

            for j in range(link.num_geom):
                geom = link.geom[j]
                # MultibodyPlant currently sets alpha=0 to make collision
                # geometry "invisible".  Ignore those geometries here.
                if geom.color[3] == 0:
                    continue

                meshcat_geom, material, element_local_tf = _convert_mesh(geom)
                if meshcat_geom is not None:
                    cur_vis = (
                        self.vis[self.prefix][source_name][str(link.robot_num)]
                        [frame_name][str(j)])
                    cur_vis.set_object(meshcat_geom, material)
                    cur_vis.set_transform(element_local_tf)
コード例 #2
0
ファイル: lcm_test.py プロジェクト: avalenzu/drake
    def test_mock_lcm(self):
        dut = DrakeMockLcm()
        self.assertIsInstance(dut, DrakeLcmInterface)

        # Create a simple ground-truth message.
        msg = quaternion_t()
        wxyz = (1, 2, 3, 4)
        msg.w, msg.x, msg.y, msg.z = wxyz

        dut.Publish(channel="TEST_CHANNEL", buffer=msg.encode())
        raw = dut.get_last_published_message("TEST_CHANNEL")
        self.assertEqual(raw, msg.encode())

        # Use an array so that we can mutate the contained value.
        called = [False]

        def handler(raw):
            msg = quaternion_t.decode(raw)
            self.assertTupleEqual((msg.w, msg.x, msg.y, msg.z), wxyz)
            called[0] = True

        dut.Subscribe(channel="TEST_CHANNEL", handler=handler)
        dut.InduceSubscriberCallback(
            channel="TEST_CHANNEL", buffer=msg.encode())
        self.assertTrue(called[0])
コード例 #3
0
ファイル: lcm_test.py プロジェクト: weiqiao/drake
 def test_publisher(self):
     lcm = DrakeMockLcm()
     dut = mut.LcmPublisherSystem.Make(
         channel="TEST_CHANNEL", lcm_type=quaternion_t, lcm=lcm,
         publish_period=0.1)
     model_message = self._model_message()
     self._fix_and_publish(dut, AbstractValue.Make(model_message))
     raw = lcm.get_last_published_message("TEST_CHANNEL")
     actual_message = quaternion_t.decode(raw)
     self.assert_lcm_equal(actual_message, model_message)
コード例 #4
0
 def test_subscriber_cpp(self):
     lcm = DrakeMockLcm()
     dut = mut.LcmSubscriberSystem.Make(channel="TEST_CHANNEL",
                                        lcm_type=quaternion_t,
                                        lcm=lcm,
                                        use_cpp_serializer=True)
     model_message = self._model_message()
     lcm.InduceSubscriberCallback(channel="TEST_CHANNEL",
                                  buffer=model_message.encode())
     actual_message = self._cpp_value_to_py_message(self._calc_output(dut))
     self.assert_lcm_equal(actual_message, model_message)
コード例 #5
0
    def test_connect_drake_visualizer(self):
        # Test visualization API.
        # Use a mockable so that we can make a smoke test without side
        # effects.
        T = float
        SceneGraph = mut.SceneGraph_[T]
        DiagramBuilder = DiagramBuilder_[T]
        Simulator = Simulator_[T]
        lcm = DrakeMockLcm()
        role = mut.Role.kIllustration
        test_prefix = "TEST_PREFIX_"

        def normal(builder, scene_graph):
            mut.ConnectDrakeVisualizer(builder=builder,
                                       scene_graph=scene_graph,
                                       lcm=lcm,
                                       role=role)
            mut.DispatchLoadMessage(scene_graph=scene_graph,
                                    lcm=lcm,
                                    role=role)

        def port(builder, scene_graph):
            mut.ConnectDrakeVisualizer(
                builder=builder,
                scene_graph=scene_graph,
                pose_bundle_output_port=(
                    scene_graph.get_pose_bundle_output_port()),
                lcm=lcm,
                role=role)
            mut.DispatchLoadMessage(scene_graph=scene_graph,
                                    lcm=lcm,
                                    role=role)

        for func in [normal, port]:
            # Create subscribers.
            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)
            # Test sequence.
            builder = DiagramBuilder()
            scene_graph = builder.AddSystem(SceneGraph())
            # Only load will be published by `DispatchLoadMessage`.
            func(builder, scene_graph)
            lcm.HandleSubscriptions(0)
            self.assertEqual(load_subscriber.count, 1)
            self.assertEqual(draw_subscriber.count, 0)
            diagram = builder.Build()
            # Load and draw will be published.
            Simulator(diagram).Initialize()
            lcm.HandleSubscriptions(0)
            self.assertEqual(load_subscriber.count, 2)
            self.assertEqual(draw_subscriber.count, 1)
コード例 #6
0
ファイル: lcm_test.py プロジェクト: weiqiao/drake
 def test_publisher_cpp(self):
     lcm = DrakeMockLcm()
     dut = mut.LcmPublisherSystem.Make(
         channel="TEST_CHANNEL", lcm_type=quaternion_t, lcm=lcm,
         use_cpp_serializer=True)
     model_message = self._model_message()
     model_value = self._model_value_cpp()
     self._fix_and_publish(dut, model_value)
     raw = lcm.get_last_published_message("TEST_CHANNEL")
     actual_message = quaternion_t.decode(raw)
     self.assert_lcm_equal(actual_message, model_message)
コード例 #7
0
 def test_publisher(self):
     lcm = DrakeMockLcm()
     dut = mut.LcmPublisherSystem.Make(channel="TEST_CHANNEL",
                                       lcm_type=quaternion_t,
                                       lcm=lcm,
                                       publish_period=0.1)
     model_message = self._model_message()
     self._fix_and_publish(dut, AbstractValue.Make(model_message))
     raw = lcm.get_last_published_message("TEST_CHANNEL")
     actual_message = quaternion_t.decode(raw)
     self.assert_lcm_equal(actual_message, model_message)
コード例 #8
0
ファイル: lcm_test.py プロジェクト: mposa/drake
 def test_publisher(self):
     lcm = DrakeMockLcm()
     dut = mut.LcmPublisherSystem.Make(
         channel="TEST_CHANNEL", lcm_type=quaternion_t, lcm=lcm)
     model = self._model_message()
     dut.set_publish_period(period=0.1)
     context = dut.CreateDefaultContext()
     context.FixInputPort(0, AbstractValue.Make(model))
     dut.Publish(context)
     raw = lcm.get_last_published_message("TEST_CHANNEL")
     value = quaternion_t.decode(raw)
     self.assert_lcm_equal(value, model)
コード例 #9
0
 def test_publisher_cpp(self):
     lcm = DrakeMockLcm()
     dut = mut.LcmPublisherSystem.Make(channel="TEST_CHANNEL",
                                       lcm_type=quaternion_t,
                                       lcm=lcm,
                                       use_cpp_serializer=True)
     subscriber = Subscriber(lcm, "TEST_CHANNEL", quaternion_t)
     model_message = self._model_message()
     model_value = self._model_value_cpp()
     self._fix_and_publish(dut, model_value)
     lcm.HandleSubscriptions(0)
     self.assert_lcm_equal(subscriber.message, model_message)
コード例 #10
0
 def test_publisher(self):
     lcm = DrakeMockLcm()
     dut = mut.LcmPublisherSystem.Make(
         channel="TEST_CHANNEL", lcm_type=quaternion_t, lcm=lcm)
     model = self._model_message()
     dut.set_publish_period(period=0.1)
     context = dut.CreateDefaultContext()
     context.FixInputPort(0, AbstractValue.Make(model))
     dut.Publish(context)
     raw = lcm.get_last_published_message("TEST_CHANNEL")
     value = quaternion_t.decode(raw)
     self.assert_lcm_equal(value, model)
コード例 #11
0
ファイル: lcm_test.py プロジェクト: peterminh227/drake
 def test_publisher_cpp(self):
     lcm = DrakeMockLcm()
     dut = mut.LcmPublisherSystem.Make(channel="TEST_CHANNEL",
                                       lcm_type=quaternion_t,
                                       lcm=lcm,
                                       use_cpp_serializer=True)
     model_message = self._model_message()
     model_value = self._model_value_cpp()
     self._fix_and_publish(dut, model_value)
     raw = lcm.get_last_published_message("TEST_CHANNEL")
     actual_message = quaternion_t.decode(raw)
     self.assert_lcm_equal(actual_message, model_message)
コード例 #12
0
 def test_subscriber(self):
     lcm = DrakeMockLcm()
     dut = mut.LcmSubscriberSystem.Make(
         channel="TEST_CHANNEL", lcm_type=quaternion_t, lcm=lcm)
     model = self._model_message()
     lcm.InduceSubscriberCallback(
         channel="TEST_CHANNEL", buffer=model.encode())
     context = dut.CreateDefaultContext()
     output = dut.AllocateOutput()
     dut.CalcOutput(context, output)
     actual = output.get_data(0).get_value()
     self.assert_lcm_equal(actual, model)
コード例 #13
0
 def test_subscriber_cpp(self):
     lcm = DrakeMockLcm()
     dut = mut.LcmSubscriberSystem.Make(
         channel="TEST_CHANNEL", lcm_type=quaternion_t, lcm=lcm,
         use_cpp_serializer=True)
     model_message = self._model_message()
     lcm.Publish(channel="TEST_CHANNEL", buffer=model_message.encode())
     lcm.HandleSubscriptions(0)
     context = self._process_event(dut)
     abstract = dut.get_output_port(0).EvalAbstract(context)
     actual_message = self._cpp_value_to_py_message(abstract)
     self.assert_lcm_equal(actual_message, model_message)
コード例 #14
0
    def load(self):
        """
        Loads ``meshcat`` visualization elements.

        Precondition:
            The ``scene_graph`` used to construct this object must be part of a
            fully constructed diagram (e.g. via ``DiagramBuilder.Build()``).
        """
        self.vis[self.prefix].delete()

        # Intercept load message via mock LCM.
        mock_lcm = DrakeMockLcm()
        mock_lcm_subscriber = Subscriber(lcm=mock_lcm,
                                         channel="DRAKE_VIEWER_LOAD_ROBOT",
                                         lcm_type=lcmt_viewer_load_robot)
        DispatchLoadMessage(self._scene_graph, mock_lcm)
        mock_lcm.HandleSubscriptions(0)
        assert mock_lcm_subscriber.count > 0
        load_robot_msg = mock_lcm_subscriber.message

        # Translate elements to `meshcat`.
        for i in range(load_robot_msg.num_links):
            link = load_robot_msg.link[i]
            [source_name, frame_name] = self._parse_name(link.name)

            for j in range(link.num_geom):
                geom = link.geom[j]
                # MultibodyPlant currently sets alpha=0 to make collision
                # geometry "invisible".  Ignore those geometries here.
                if geom.color[3] == 0:
                    continue

                meshcat_geom, material, element_local_tf = _convert_mesh(geom)
                if meshcat_geom is not None:
                    cur_vis = (self.vis[self.prefix][source_name][str(
                        link.robot_num)][frame_name][str(j)])
                    cur_vis.set_object(meshcat_geom, material)
                    cur_vis.set_transform(element_local_tf)

                # Draw the frames in self.frames_to_draw.
                robot_name, link_name = self._parse_name(frame_name)
                if (robot_name in self.frames_to_draw.keys()
                        and link_name in self.frames_to_draw[robot_name]):
                    prefix = (self.prefix + '/' + source_name + '/' +
                              str(link.robot_num) + '/' + frame_name)
                    AddTriad(self.vis,
                             name="frame",
                             prefix=prefix,
                             length=self.axis_length,
                             radius=self.axis_radius,
                             opacity=self.frames_opacity)
コード例 #15
0
ファイル: geometry_test.py プロジェクト: yazici/drake
    def test_connect_drake_visualizer(self):
        # Test visualization API.
        # Use a mockable so that we can make a smoke test without side
        # effects.
        T = float
        SceneGraph = mut.SceneGraph_[T]
        DiagramBuilder = DiagramBuilder_[T]
        lcm = DrakeMockLcm()

        for role in [mut.Role.kProximity, mut.Role.kIllustration]:
            for i in range(2):
                builder = DiagramBuilder()
                scene_graph = builder.AddSystem(SceneGraph())
                if i == 1:
                    mut.ConnectDrakeVisualizer(builder=builder,
                                               scene_graph=scene_graph,
                                               lcm=lcm,
                                               role=role)
                else:
                    mut.ConnectDrakeVisualizer(
                        builder=builder,
                        scene_graph=scene_graph,
                        pose_bundle_output_port=(
                            scene_graph.get_pose_bundle_output_port()),
                        lcm=lcm,
                        role=role)
                mut.DispatchLoadMessage(scene_graph=scene_graph,
                                        lcm=lcm,
                                        role=role)
コード例 #16
0
ファイル: geometry_test.py プロジェクト: yapengshi/drake
 def test_scene_graph_api(self):
     scene_graph = mut.SceneGraph()
     global_source = scene_graph.RegisterSource("anchored")
     self.assertIsInstance(
         scene_graph.get_source_pose_port(global_source), InputPort)
     self.assertIsInstance(
         scene_graph.get_pose_bundle_output_port(), OutputPort)
     self.assertIsInstance(
         scene_graph.get_query_output_port(), OutputPort)
     # Test visualization API.
     # Use a mockable so that we can make a smoke test without side effects.
     lcm = DrakeMockLcm()
     for i in range(2):
         builder = DiagramBuilder()
         scene_graph = builder.AddSystem(mut.SceneGraph())
         if i == 1:
             mut.ConnectDrakeVisualizer(
                 builder=builder, scene_graph=scene_graph)
         else:
             mut.ConnectDrakeVisualizer(
                 builder=builder, scene_graph=scene_graph,
                 pose_bundle_output_port=(
                     scene_graph.get_pose_bundle_output_port()))
         mut.DispatchLoadMessage(
             scene_graph=scene_graph, lcm=lcm)
コード例 #17
0
ファイル: lcm_test.py プロジェクト: peterminh227/drake
 def test_connect_lcm_scope(self):
     builder = DiagramBuilder()
     source = builder.AddSystem(ConstantVectorSource(np.zeros(4)))
     mut.ConnectLcmScope(src=source.get_output_port(0),
                         channel="TEST_CHANNEL",
                         builder=builder,
                         lcm=DrakeMockLcm())
コード例 #18
0
 def test_subscriber(self):
     mock = DrakeMockLcm()
     dut = Subscriber(lcm=mock, channel="CHANNEL", lcm_type=quaternion_t)
     mock.Publish(channel="CHANNEL", buffer=self.quat.encode())
     self.assertEqual(dut.count, 0)
     self.assertEqual(len(dut.raw), 0)
     self.assertEqual(dut.message.w, 0)
     self.assertEqual(dut.message.x, 0)
     self.assertEqual(dut.message.y, 0)
     self.assertEqual(dut.message.z, 0)
     mock.HandleSubscriptions(0)
     self.assertEqual(dut.count, 1)
     self.assertEqual(dut.raw, self.quat.encode())
     self.assertEqual(dut.message.w, self.quat.w)
     self.assertEqual(dut.message.x, self.quat.x)
     self.assertEqual(dut.message.y, self.quat.y)
     self.assertEqual(dut.message.z, self.quat.z)
コード例 #19
0
ファイル: utils.py プロジェクト: atwang16/6-881-examples
def get_box_from_geom(scene_graph, visual_only=True):
    # https://github.com/RussTedrake/underactuated/blob/master/src/underactuated/meshcat_visualizer.py
    # https://github.com/RobotLocomotion/drake/blob/master/lcmtypes/lcmt_viewer_draw.lcm
    mock_lcm = DrakeMockLcm()
    DispatchLoadMessage(scene_graph, mock_lcm)
    load_robot_msg = lcmt_viewer_load_robot.decode(
        mock_lcm.get_last_published_message("DRAKE_VIEWER_LOAD_ROBOT"))

    box_from_geom = {}
    for body_index in range(load_robot_msg.num_links):
        # 'geom', 'name', 'num_geom', 'robot_num'
        link = load_robot_msg.link[body_index]
        [source_name, frame_name] = link.name.split("::")
        model_index = link.robot_num

        visual_index = 0
        for geom in sorted(link.geom,
                           key=lambda g: g.position[::-1]):  # sort by z, y, x
            # 'color', 'float_data', 'num_float_data', 'position', 'quaternion', 'string_data', 'type'
            if visual_only and (geom.color[3] == 0):
                continue

            visual_index += 1
            if geom.type == geom.BOX:
                assert geom.num_float_data == 3
                [width, length, height] = geom.float_data
                extent = np.array([width, length, height]) / 2.
            elif geom.type == geom.SPHERE:
                assert geom.num_float_data == 1
                [radius] = geom.float_data
                extent = np.array([radius, radius, radius])
            elif geom.type == geom.CYLINDER:
                assert geom.num_float_data == 2
                [radius, height] = geom.float_data
                extent = np.array([radius, radius, height / 2.])
                # In Drake, cylinders are along +z
            else:
                continue
            link_from_box = RigidTransform(
                RotationMatrix(Quaternion(geom.quaternion)),
                geom.position).GetAsIsometry3()
            box_from_geom[model_index, frame_name, visual_index-1] = \
                (BoundingBox(np.zeros(3), extent), link_from_box, get_geom_name(geom))
    return box_from_geom
コード例 #20
0
    def load(self):
        """
        Loads ``meshcat`` visualization elements.

        Precondition:
            The ``scene_graph`` used to construct this object must be part of a
            fully constructed diagram (e.g. via ``DiagramBuilder.Build()``).
        """
        self.vis[self.prefix].delete()

        # Intercept load message via mock LCM.
        def handle_load_robot(raw):
            load_robot_msgs.append(lcmt_viewer_load_robot.decode(raw))
        load_robot_msgs = []
        mock_lcm = DrakeMockLcm()
        mock_lcm.Subscribe(
            channel="DRAKE_VIEWER_LOAD_ROBOT",
            handler=handle_load_robot)
        DispatchLoadMessage(self._scene_graph, mock_lcm)
        mock_lcm.HandleSubscriptions(0)
        load_robot_msg = load_robot_msgs[0]
        # Translate elements to `meshcat`.
        for i in range(load_robot_msg.num_links):
            link = load_robot_msg.link[i]
            [source_name, frame_name] = self._parse_name(link.name)

            for j in range(link.num_geom):
                geom = link.geom[j]
                # MultibodyPlant currently sets alpha=0 to make collision
                # geometry "invisible".  Ignore those geometries here.
                if geom.color[3] == 0:
                    continue

                meshcat_geom, material, element_local_tf = _convert_mesh(geom)
                if meshcat_geom is not None:
                    cur_vis = (
                        self.vis[self.prefix][source_name][str(link.robot_num)]
                        [frame_name][str(j)])
                    cur_vis.set_object(meshcat_geom, material)
                    cur_vis.set_transform(element_local_tf)
コード例 #21
0
 def test_drake_visualizer_api(self):
     tree = self._make_tree()
     lcm = DrakeMockLcm()
     # Test for existence.
     viz = mut.DrakeVisualizer(tree=tree, lcm=lcm, enable_playback=True)
     viz.set_publish_period(period=0.01)
     # - Force publish to ensure we have enough knot points.
     context = viz.CreateDefaultContext()
     x0 = np.zeros(tree.get_num_positions() + tree.get_num_velocities())
     context.FixInputPort(0, BasicVector(x0))
     context.set_time(0.)
     viz.Publish(context)
     # Use a small time period, since it uses realtime playback.
     context.set_time(0.01)
     viz.Publish(context)
     viz.ReplayCachedSimulation()
コード例 #22
0
 def test_drake_visualizer_api(self):
     tree = self._make_tree()
     lcm = DrakeMockLcm()
     # Test for existence.
     viz = mut.DrakeVisualizer(tree=tree, lcm=lcm, enable_playback=True)
     viz.set_publish_period(period=0.01)
     # - Force publish to ensure we have enough knot points.
     context = viz.CreateDefaultContext()
     x0 = np.zeros(tree.get_num_positions() + tree.get_num_velocities())
     viz.get_input_port(0).FixValue(context, x0)
     context.SetTime(0.)
     viz.Publish(context)
     # Use a small time period, since it uses realtime playback.
     context.SetTime(0.01)
     viz.Publish(context)
     viz.ReplayCachedSimulation()
     # - Check that PublishLoadRobot can be called.
     viz.PublishLoadRobot()
コード例 #23
0
    def load(self):
        """
        Loads all visualization elements in the Blender server.

        @pre The `scene_graph` used to construct this object must be part of a
        fully constructed diagram (e.g. via `DiagramBuilder.Build()`).
        """
        self.bsi.send_remote_call("initialize_scene")

        # Intercept load message via mock LCM.
        mock_lcm = DrakeMockLcm()
        mock_lcm_subscriber = Subscriber(lcm=mock_lcm,
                                         channel="DRAKE_VIEWER_LOAD_ROBOT",
                                         lcm_type=lcmt_viewer_load_robot)
        DispatchLoadMessage(self._scene_graph, mock_lcm)
        mock_lcm.HandleSubscriptions(0)
        assert mock_lcm_subscriber.count > 0
        load_robot_msg = mock_lcm_subscriber.message

        # Load all the elements over on the Blender side.
        self.num_link_geometries_by_link_name = {}
        self.link_subgeometry_local_tfs_by_link_name = {}
        self.geom_name_to_color_map = {}
        num_allocated_labels = 0
        max_num_objs = sum([
            load_robot_msg.link[i].num_geom
            for i in range(load_robot_msg.num_links)
        ])
        cmap = plt.cm.get_cmap("hsv", max_num_objs + 1)
        for i in range(load_robot_msg.num_links):
            link = load_robot_msg.link[i]
            [source_name, frame_name] = self._parse_name(link.name)
            self.num_link_geometries_by_link_name[link.name] = link.num_geom

            tfs = []
            for j in range(link.num_geom):
                geom = link.geom[j]

                # MultibodyPlant currently sets alpha=0 to make collision
                # geometry "invisible".  Ignore those geometries here.
                if geom.color[3] == 0:
                    continue

                geom_name = self._format_geom_name(source_name, frame_name,
                                                   link.robot_num, j)

                tfs.append(
                    RigidTransform(RotationMatrix(Quaternion(geom.quaternion)),
                                   geom.position).GetAsMatrix4())

                # It will have a material with this key.
                material_key = "material_" + geom_name
                label_num = num_allocated_labels
                self.geom_name_to_color_map[geom_name] = cmap(label_num)
                num_allocated_labels += 1

                material_key_assigned = self.bsi.send_remote_call(
                    "register_material",
                    name=material_key,
                    material_type="emission",
                    color=cmap(label_num))

                if geom.type == geom.BOX:
                    assert geom.num_float_data == 3
                    # Blender cubes are 2x2x2 by default
                    self.bsi.send_remote_call(
                        "register_object",
                        name="obj_" + geom_name,
                        type="cube",
                        scale=[x * 0.5 for x in geom.float_data[:3]],
                        location=geom.position,
                        quaternion=geom.quaternion,
                        material=material_key)

                elif geom.type == geom.SPHERE:
                    assert geom.num_float_data == 1
                    self.bsi.send_remote_call("register_object",
                                              name="obj_" + geom_name,
                                              type="sphere",
                                              scale=geom.float_data[0],
                                              location=geom.position,
                                              quaternion=geom.quaternion,
                                              material=material_key)

                elif geom.type == geom.CYLINDER:
                    assert geom.num_float_data == 2
                    # Blender cylinders are r=1, h=2 by default
                    self.bsi.send_remote_call("register_object",
                                              name="obj_" + geom_name,
                                              type="cylinder",
                                              scale=[
                                                  geom.float_data[0],
                                                  geom.float_data[0],
                                                  0.5 * geom.float_data[1]
                                              ],
                                              location=geom.position,
                                              quaternion=geom.quaternion,
                                              material=material_key)

                elif geom.type == geom.MESH:
                    self.bsi.send_remote_call("register_object",
                                              name="obj_" + geom_name,
                                              type="obj",
                                              path=geom.string_data[0:-3] +
                                              "obj",
                                              scale=geom.float_data[:3],
                                              location=geom.position,
                                              quaternion=geom.quaternion,
                                              material=material_key)

                else:
                    print("UNSUPPORTED GEOMETRY TYPE {} IGNORED".format(
                        geom.type))
                    continue

            self.link_subgeometry_local_tfs_by_link_name[link.name] = tfs

        for i, camera_tf in enumerate(self.camera_tfs):
            camera_tf_post = self.global_transform.multiply(camera_tf)
            self.bsi.send_remote_call(
                "register_camera",
                name="cam_%d" % i,
                location=camera_tf_post.translation().tolist(),
                quaternion=camera_tf_post.rotation().ToQuaternion().wxyz(
                ).tolist(),
                angle=np.pi / 2.)

            self.bsi.send_remote_call("configure_rendering",
                                      camera_name='cam_%d' % i,
                                      resolution=[640, 480],
                                      file_format="BMP",
                                      configure_for_masks=True,
                                      taa_render_samples=10,
                                      cycles=False)

        self.bsi.send_remote_call("set_environment_map", path=None)
コード例 #24
0
 def test_mock_lcm_induce_subscriber_callback(self):
     dut = DrakeMockLcm()
     dut.Subscribe(channel="TEST_CHANNEL", handler=self._handler)
     dut.InduceSubscriberCallback(channel="TEST_CHANNEL",
                                  buffer=self.quat.encode())
     self.assertEqual(self.count, 1)
コード例 #25
0
ファイル: utils.py プロジェクト: yqj13777866390/pddlstream
def get_box_from_geom(scene_graph, visual_only=True):
    # TODO: GeometryInstance, InternalGeometry, & GeometryContext to get the shape of objects
    # TODO: get_contact_results_output_port
    # https://github.com/RussTedrake/underactuated/blob/master/src/underactuated/meshcat_visualizer.py
    # https://github.com/RobotLocomotion/drake/blob/master/lcmtypes/lcmt_viewer_draw.lcm
    mock_lcm = DrakeMockLcm()
    DispatchLoadMessage(scene_graph, mock_lcm)
    load_robot_msg = lcmt_viewer_load_robot.decode(
        mock_lcm.get_last_published_message("DRAKE_VIEWER_LOAD_ROBOT"))
    # 'link', 'num_links'
    #builder.Connect(scene_graph.get_pose_bundle_output_port(),
    #                viz.get_input_port(0))

    # TODO: hash bodies instead
    box_from_geom = {}
    for body_index in range(load_robot_msg.num_links):
        # 'geom', 'name', 'num_geom', 'robot_num'
        link = load_robot_msg.link[body_index]
        [source_name, frame_name] = link.name.split("::")
        # source_name = 'Source_1'
        model_index = link.robot_num

        visual_index = 0
        for geom in sorted(link.geom,
                           key=lambda g: g.position[::-1]):  # sort by z, y, x
            # 'color', 'float_data', 'num_float_data', 'position', 'quaternion', 'string_data', 'type'
            # string_data is empty...
            if visual_only and (geom.color[3] == 0):
                continue

            # TODO: sort by lowest point on the bounding box?
            # TODO: maybe just return the set of bodies in order and let the user decide what to with them
            visual_index += 1  # TODO: affected by transparent visual
            if geom.type == geom.BOX:
                assert geom.num_float_data == 3
                [width, length, height] = geom.float_data
                extent = np.array([width, length, height]) / 2.
            elif geom.type == geom.SPHERE:
                assert geom.num_float_data == 1
                [radius] = geom.float_data
                extent = np.array([radius, radius, radius])
            elif geom.type == geom.CYLINDER:
                assert geom.num_float_data == 2
                [radius, height] = geom.float_data
                extent = np.array([radius, radius, height / 2.])
                #meshcat_geom = meshcat.geometry.Cylinder(
                #    geom.float_data[1], geom.float_data[0])
                # In Drake, cylinders are along +z
            #elif geom.type == geom.MESH:
            #    meshcat_geom = meshcat.geometry.ObjMeshGeometry.from_file(
            #            geom.string_data[0:-3] + "obj")
            else:
                #print("Robot {}, link {}, geometry {}: UNSUPPORTED GEOMETRY TYPE {} WAS IGNORED".format(
                #    model_index, frame_name, visual_index-1, geom.type))
                continue
            link_from_box = RigidTransform(
                RotationMatrix(Quaternion(geom.quaternion)),
                geom.position).GetAsIsometry3()  #.GetAsMatrix4()
            box_from_geom[model_index, frame_name, visual_index-1] = \
                (BoundingBox(np.zeros(3), extent), link_from_box, get_geom_name(geom))
    return box_from_geom
コード例 #26
0
 def test_mock_lcm_get_last_published_message_deprecated(self):
     dut = DrakeMockLcm()
     dut.Publish(channel="TEST_CHANNEL", buffer=self.quat.encode())
     with catch_drake_warnings(expected_count=1):
         raw = dut.get_last_published_message("TEST_CHANNEL")
         self.assertEqual(raw, self.quat.encode())
コード例 #27
0
ファイル: meshcat_visualizer.py プロジェクト: mposa/drake
    def load(self):
        """
        Loads `meshcat` visualization elements.

        @pre The `scene_graph` used to construct this object must be part of a
        fully constructed diagram (e.g. via `DiagramBuilder.Build()`).
        """
        self.vis[self.prefix].delete()

        # Intercept load message via mock LCM.
        mock_lcm = DrakeMockLcm()
        DispatchLoadMessage(self._scene_graph, mock_lcm)
        load_robot_msg = lcmt_viewer_load_robot.decode(
            mock_lcm.get_last_published_message("DRAKE_VIEWER_LOAD_ROBOT"))
        # Translate elements to `meshcat`.
        for i in range(load_robot_msg.num_links):
            link = load_robot_msg.link[i]
            [source_name, frame_name] = link.name.split("::")

            for j in range(link.num_geom):
                geom = link.geom[j]
                # MultibodyPlant currenly sets alpha=0 to make collision
                # geometry "invisible".  Ignore those geometries here.
                if geom.color[3] == 0:
                    continue

                element_local_tf = RigidTransform(
                    RotationMatrix(Quaternion(geom.quaternion)),
                    geom.position).GetAsMatrix4()

                if geom.type == geom.BOX:
                    assert geom.num_float_data == 3
                    meshcat_geom = meshcat.geometry.Box(geom.float_data)
                elif geom.type == geom.SPHERE:
                    assert geom.num_float_data == 1
                    meshcat_geom = meshcat.geometry.Sphere(geom.float_data[0])
                elif geom.type == geom.CYLINDER:
                    assert geom.num_float_data == 2
                    meshcat_geom = meshcat.geometry.Cylinder(
                        geom.float_data[1],
                        geom.float_data[0])
                    # In Drake, cylinders are along +z
                    # In meshcat, cylinders are along +y
                    # Rotate to fix this misalignment
                    extra_rotation = tf.rotation_matrix(
                        math.pi/2., [1, 0, 0])
                    element_local_tf[0:3, 0:3] = \
                        element_local_tf[0:3, 0:3].dot(
                            extra_rotation[0:3, 0:3])
                elif geom.type == geom.MESH:
                    meshcat_geom = \
                        meshcat.geometry.ObjMeshGeometry.from_file(
                            geom.string_data[0:-3] + "obj")
                else:
                    print("UNSUPPORTED GEOMETRY TYPE {} IGNORED".format(
                          geom.type))
                    continue

                # Turn a list of R,G,B elements (any indexable list of >= 3
                # elements will work), where each element is specified on range
                # [0., 1.], into the equivalent 24-bit value 0xRRGGBB.
                def Rgb2Hex(rgb):
                    val = 0
                    for i in range(3):
                        val += (256**(2 - i)) * int(255 * rgb[i])
                    return val

                self.vis[self.prefix][source_name][str(link.robot_num)][
                    frame_name][str(j)]\
                    .set_object(meshcat_geom,
                                meshcat.geometry
                                .MeshLambertMaterial(
                                    color=Rgb2Hex(geom.color)))
                self.vis[self.prefix][source_name][str(link.robot_num)][
                    frame_name][str(j)].set_transform(element_local_tf)
コード例 #28
0
ファイル: lcm_test.py プロジェクト: RobotLocomotion/drake
 def test_mock_lcm_get_last_published_message_deprecated(self):
     dut = DrakeMockLcm()
     dut.Publish(channel="TEST_CHANNEL", buffer=self.quat.encode())
     with catch_drake_warnings(expected_count=1):
         raw = dut.get_last_published_message("TEST_CHANNEL")
         self.assertEqual(raw, self.quat.encode())
コード例 #29
0
    def buildViewPatches(self, use_random_colors):
        ''' Generates view patches. self.viewPatches stores a list of
        viewPatches for each body (starting at body id 1). A viewPatch is a
        list of all 3D vertices of a piece of visual geometry. '''

        self.viewPatches = {}
        self.viewPatchColors = {}

        mock_lcm = DrakeMockLcm()
        mock_lcm_subscriber = Subscriber(lcm=mock_lcm,
                                         channel="DRAKE_VIEWER_LOAD_ROBOT",
                                         lcm_type=lcmt_viewer_load_robot)
        DispatchLoadMessage(self._scene_graph, mock_lcm)
        mock_lcm.HandleSubscriptions(0)
        assert mock_lcm_subscriber.count > 0
        load_robot_msg = mock_lcm_subscriber.message

        # Spawn a random color generator, in case we need to pick
        # random colors for some bodies. Each body will be given
        # a unique color when using this random generator, with
        # each visual element of the body colored the same.
        color = iter(
            plt.cm.rainbow(np.linspace(0, 1, load_robot_msg.num_links)))

        for i in range(load_robot_msg.num_links):
            link = load_robot_msg.link[i]

            this_body_patches = []
            this_body_colors = []
            this_color = next(color)

            for j in range(link.num_geom):
                geom = link.geom[j]
                # MultibodyPlant currently sets alpha=0 to make collision
                # geometry "invisible".  Ignore those geometries here.
                if geom.color[3] == 0:
                    continue

                element_local_tf = RigidTransform(
                    RotationMatrix(Quaternion(geom.quaternion)), geom.position)

                if geom.type == geom.BOX:
                    assert geom.num_float_data == 3

                    # Draw a bounding box.
                    patch = np.vstack((geom.float_data[0] / 2. *
                                       np.array([-1, -1, 1, 1, -1, -1, 1, 1]),
                                       geom.float_data[1] / 2. *
                                       np.array([-1, 1, -1, 1, -1, 1, -1, 1]),
                                       geom.float_data[2] / 2. *
                                       np.array([-1, -1, -1, -1, 1, 1, 1, 1])))

                elif geom.type == geom.SPHERE:
                    assert geom.num_float_data == 1
                    radius = geom.float_data[0]
                    lati, longi = np.meshgrid(np.arange(0., 2. * math.pi, 0.5),
                                              np.arange(0., 2. * math.pi, 0.5))
                    lati = lati.ravel()
                    longi = longi.ravel()
                    patch = np.vstack([
                        np.sin(longi) * np.cos(lati),
                        np.sin(longi) * np.sin(lati),
                        np.cos(lati)
                    ])
                    patch *= radius

                elif geom.type == geom.CYLINDER:
                    assert geom.num_float_data == 2
                    radius = geom.float_data[0]
                    length = geom.float_data[1]

                    # In the lcm geometry, cylinders are along +z
                    # https://github.com/RobotLocomotion/drake/blob/last_sha_with_original_matlab/drake/matlab/systems/plants/RigidBodyCylinder.m
                    # Two circles: one at bottom, one at top.
                    sample_pts = np.arange(0., 2. * math.pi, 0.25)
                    patch = np.hstack([
                        np.array([[
                            radius * math.cos(pt), radius * math.sin(pt),
                            -length / 2.
                        ],
                                  [
                                      radius * math.cos(pt),
                                      radius * math.sin(pt), length / 2.
                                  ]]).T for pt in sample_pts
                    ])

                elif geom.type == geom.MESH:
                    # TODO(gizatt): Remove trimesh and shapely dependency when
                    # vertex information is accessible from the SceneGraph
                    # interface.
                    mesh = trimesh.load(geom.string_data)
                    patch = mesh.vertices.T
                    # Apply scaling
                    for i in range(3):
                        patch[i, :] *= geom.float_data[i]

                else:
                    print("UNSUPPORTED GEOMETRY TYPE {} IGNORED".format(
                        geom.type))
                    continue

                patch = np.vstack((patch, np.ones((1, patch.shape[1]))))
                patch = np.dot(element_local_tf.GetAsMatrix4(), patch)

                # Close path if not closed
                if (patch[:, -1] != patch[:, 0]).any():
                    patch = np.hstack((patch, patch[:, 0][np.newaxis].T))

                this_body_patches.append(patch)
                if use_random_colors:
                    this_body_colors.append(this_color)
                else:
                    this_body_colors.append(geom.color)

            self.viewPatches[link.name] = this_body_patches
            self.viewPatchColors[link.name] = this_body_colors
コード例 #30
0
ファイル: lcm_test.py プロジェクト: Damonvid/drake
 def test_mock_lcm(self):
     self._test_lcm_interface(DrakeMockLcm())
コード例 #31
0
ファイル: lcm_test.py プロジェクト: weiqiao/drake
 def test_mock_lcm_get_last_published_message(self):
     dut = DrakeMockLcm()
     dut.Publish(channel="TEST_CHANNEL", buffer=self.quat.encode())
     raw = dut.get_last_published_message("TEST_CHANNEL")
     self.assertEqual(raw, self.quat.encode())
コード例 #32
0
    def load(self):
        """
        Loads `meshcat` visualization elements.

        @pre The `scene_graph` used to construct this object must be part of a
        fully constructed diagram (e.g. via `DiagramBuilder.Build()`).
        """
        self.vis[self.prefix].delete()

        # Intercept load message via mock LCM.
        mock_lcm = DrakeMockLcm()
        DispatchLoadMessage(self._scene_graph, mock_lcm)
        load_robot_msg = lcmt_viewer_load_robot.decode(
            mock_lcm.get_last_published_message("DRAKE_VIEWER_LOAD_ROBOT"))
        # Translate elements to `meshcat`.
        for i in range(load_robot_msg.num_links):
            link = load_robot_msg.link[i]
            [source_name, frame_name] = link.name.split("::")

            for j in range(link.num_geom):
                geom = link.geom[j]
                # MultibodyPlant currenly sets alpha=0 to make collision
                # geometry "invisible".  Ignore those geometries here.
                if geom.color[3] == 0:
                    continue

                element_local_tf = RigidTransform(
                    RotationMatrix(Quaternion(geom.quaternion)),
                    geom.position).GetAsMatrix4()

                if geom.type == geom.BOX:
                    assert geom.num_float_data == 3
                    meshcat_geom = meshcat.geometry.Box(geom.float_data)
                elif geom.type == geom.SPHERE:
                    assert geom.num_float_data == 1
                    meshcat_geom = meshcat.geometry.Sphere(geom.float_data[0])
                elif geom.type == geom.CYLINDER:
                    assert geom.num_float_data == 2
                    meshcat_geom = meshcat.geometry.Cylinder(
                        geom.float_data[1], geom.float_data[0])
                    # In Drake, cylinders are along +z
                    # In meshcat, cylinders are along +y
                    # Rotate to fix this misalignment
                    extra_rotation = tf.rotation_matrix(
                        math.pi / 2., [1, 0, 0])
                    element_local_tf[0:3, 0:3] = \
                        element_local_tf[0:3, 0:3].dot(
                            extra_rotation[0:3, 0:3])
                elif geom.type == geom.MESH:
                    meshcat_geom = \
                        meshcat.geometry.ObjMeshGeometry.from_file(
                            geom.string_data[0:-3] + "obj")
                else:
                    print "UNSUPPORTED GEOMETRY TYPE ", \
                        geom.type, " IGNORED"
                    continue

                # Turn a list of R,G,B elements (any indexable list of >= 3
                # elements will work), where each element is specified on range
                # [0., 1.], into the equivalent 24-bit value 0xRRGGBB.
                def Rgb2Hex(rgb):
                    val = 0
                    for i in range(3):
                        val += (256**(2 - i)) * int(255 * rgb[i])
                    return val

                self.vis[self.prefix][source_name][str(link.robot_num)][
                    frame_name][str(j)]\
                    .set_object(meshcat_geom,
                                meshcat.geometry
                                .MeshLambertMaterial(
                                    color=Rgb2Hex(geom.color)))
                self.vis[self.prefix][source_name][str(
                    link.robot_num)][frame_name][str(j)].set_transform(
                        element_local_tf)
コード例 #33
0
ファイル: lcm_test.py プロジェクト: ethanweber/atlas-drake
 def test_mock_lcm(self):
     dut = DrakeMockLcm()
     self.assertIsInstance(dut, DrakeLcmInterface)
コード例 #34
0
    def load1(self):
        """
        Loads all visualization elements in the Blender server.

        @pre The `scene_graph` used to construct this object must be part of a
        fully constructed diagram (e.g. via `DiagramBuilder.Build()`).
        """
        self.bsi.send_remote_call("initialize_scene")

        # Keeps track of registered bounding boxes, to keep us from
        # having to register + delete brand new objects every cycle.
        # If more than this number is needed in a given cycle,
        # more are registered and this number is increased.
        # If less are needed, the unused ones are made invisible.
        # The attributes of all bounding boxes are updated every cycle.
        self.num_registered_bounding_boxes = 0
        self.num_visible_bounding_boxes = 0

        # Intercept load message via mock LCM.
        mock_lcm = DrakeMockLcm()
        mock_lcm_subscriber = Subscriber(lcm=mock_lcm,
                                         channel="DRAKE_VIEWER_LOAD_ROBOT",
                                         lcm_type=lcmt_viewer_load_robot)

        # warnings.filterwarnings("ignore", message="(Advanced) Explicitly dispatches an LCM load message")
        warnings.simplefilter("ignore", DrakeDeprecationWarning)
        DispatchLoadMessage(self._scene_graph, mock_lcm)
        # SendLoadMessage()  TODO
        mock_lcm.HandleSubscriptions(0)
        assert mock_lcm_subscriber.count > 0
        load_robot_msg = mock_lcm_subscriber.message

        # Load all the elements over on the Blender side.
        self.num_link_geometries_by_link_name = {}
        self.link_subgeometry_local_tfs_by_link_name = {}
        for i in range(load_robot_msg.num_links):
            link = load_robot_msg.link[i]
            [source_name, frame_name] = self._parse_name(link.name)
            print('frame_name', frame_name)
            print('link.name', link.name)
            self.num_link_geometries_by_link_name[link.name] = link.num_geom

            tfs = []
            for j in range(link.num_geom):
                geom = link.geom[j]

                # MultibodyPlant currently sets alpha=0 to make collision
                # geometry "invisible".  Ignore those geometries here.
                if geom.color[3] == 0:
                    continue

                geom_name = self._format_geom_name(source_name, frame_name, j)

                tfs.append(
                    RigidTransform(RotationMatrix(Quaternion(geom.quaternion)),
                                   geom.position).GetAsMatrix4())

                # It will have a material with this key.
                # We will set it up after deciding whether it's
                # a mesh with a texture or not...
                material_key = "material_" + geom_name
                material_key_assigned = False

                # Check overrides
                for override in self.material_overrides:
                    if override[0].match(geom_name):
                        print("Using override ", override[0].pattern,
                              " on name ", geom_name, " with applied args ",
                              override[1])
                        self.bsi.send_remote_call("register_material",
                                                  name=material_key,
                                                  **(override[1]))
                        material_key_assigned = True

                if geom.type == geom.BOX:
                    assert geom.num_float_data == 3
                    # Blender cubes are 2x2x2 by default
                    do_load_geom = lambda: self.bsi.send_remote_call(
                        "register_object",
                        name="obj_" + geom_name,
                        type="cube",
                        scale=[x * 0.5 for x in geom.float_data[:3]],
                        location=geom.position,
                        quaternion=geom.quaternion,
                        material=material_key)

                elif geom.type == geom.SPHERE:
                    assert geom.num_float_data == 1
                    do_load_geom = lambda: self.bsi.send_remote_call(
                        "register_object",
                        name="obj_" + geom_name,
                        type="sphere",
                        scale=geom.float_data[0],
                        location=geom.position,
                        quaternion=geom.quaternion,
                        material=material_key)

                elif geom.type == geom.CYLINDER:
                    assert geom.num_float_data == 2
                    # Blender cylinders are r=1, h=2 by default
                    do_load_geom = lambda: self.bsi.send_remote_call(
                        "register_object",
                        name="obj_" + geom_name,
                        type="cylinder",
                        scale=[
                            geom.float_data[0], geom.float_data[0], 0.5 * geom.
                            float_data[1]
                        ],
                        location=geom.position,
                        quaternion=geom.quaternion,
                        material=material_key)

                elif geom.type == geom.MESH:
                    print('geom_name', geom_name)
                    print('path', geom.string_data[0:-3])
                    print('scale', geom.float_data[:3])
                    print('loc', geom.position)
                    print('quat', geom.quaternion)
                    print('material_key', material_key)
                    do_load_geom = lambda: self.bsi.send_remote_call(
                        "register_object",
                        name="obj_" + geom_name,
                        type="obj",
                        path=geom.string_data[0:-3] + "obj",
                        scale=geom.float_data[:3],
                        location=geom.position,
                        quaternion=geom.quaternion,
                        material=material_key)

                    # Attempt to find a texture for the object by looking for an
                    # identically-named *.png next to the model.
                    # TODO(gizatt): In the long term, this kind of material information
                    # should be gleaned from the SceneGraph constituents themselves, so
                    # that we visualize what the simulation is *actually* reasoning about
                    # rather than what files happen to be present.
                    candidate_texture_path_png = geom.string_data[0:-3] + "png"
                    if not material_key_assigned and os.path.exists(
                            candidate_texture_path_png):
                        material_key_assigned = self.bsi.send_remote_call(
                            "register_material",
                            name=material_key,
                            material_type="color_texture",
                            path=candidate_texture_path_png)

                else:
                    print("UNSUPPORTED GEOMETRY TYPE {} IGNORED".format(
                        geom.type))
                    continue

                if not material_key_assigned:
                    material_key_assigned = self.bsi.send_remote_call(
                        "register_material",
                        name=material_key,
                        material_type="color",
                        color=geom.color[:4])
                    print('color', geom.color[:4])

                # Finally actually load the geometry now that the material
                # is registered.
                do_load_geom()

            self.link_subgeometry_local_tfs_by_link_name[link.name] = tfs

        for i, camera_tf in enumerate(self.camera_tfs):
            camera_tf_post = self.global_transform.multiply(camera_tf)
            self.bsi.send_remote_call(
                "register_camera",
                name="cam_%d" % i,
                location=camera_tf_post.translation().tolist(),
                quaternion=camera_tf_post.quaternion().wxyz().tolist(),
                angle=np.pi / 2.)

            self.bsi.send_remote_call("configure_rendering",
                                      camera_name='cam_%d' % i,
                                      resolution=[640, 480],
                                      file_format="JPEG",
                                      taa_render_samples=20,
                                      cycles=True)

        if self.env_map_path:
            self.bsi.send_remote_call("set_environment_map",
                                      path=self.env_map_path)
コード例 #35
0
 def test_mock_lcm_get_last_published_message(self):
     dut = DrakeMockLcm()
     dut.Publish(channel="TEST_CHANNEL", buffer=self.quat.encode())
     raw = dut.get_last_published_message("TEST_CHANNEL")
     self.assertEqual(raw, self.quat.encode())
コード例 #36
0
    def buildViewPatches(self, use_random_colors):
        ''' Generates view patches. self.viewPatches stores a list of
        viewPatches for each body (starting at body id 1). A viewPatch is a
        list of 2D coordinates in counterclockwise order forming the boundary
        of a filled polygon representing a piece of visual geometry. '''

        self.viewPatches = {}
        self.viewPatchColors = {}

        mock_lcm = DrakeMockLcm()
        mock_lcm_subscriber = Subscriber(lcm=mock_lcm,
                                         channel="DRAKE_VIEWER_LOAD_ROBOT",
                                         lcm_type=lcmt_viewer_load_robot)
        DispatchLoadMessage(self._scene_graph, mock_lcm)
        mock_lcm.HandleSubscriptions(0)
        assert mock_lcm_subscriber.count > 0
        load_robot_msg = mock_lcm_subscriber.message

        # Spawn a random color generator, in case we need to pick
        # random colors for some bodies. Each body will be given
        # a unique color when using this random generator, with
        # each visual element of the body colored the same.
        color = iter(plt.cm.rainbow(np.linspace(0, 1,
                                                load_robot_msg.num_links)))

        for i in range(load_robot_msg.num_links):
            link = load_robot_msg.link[i]

            this_body_patches = []
            this_body_colors = []
            this_color = next(color)

            for j in range(link.num_geom):
                geom = link.geom[j]
                # MultibodyPlant currently sets alpha=0 to make collision
                # geometry "invisible".  Ignore those geometries here.
                if geom.color[3] == 0:
                    continue

                element_local_tf = RigidTransform(
                    RotationMatrix(Quaternion(geom.quaternion)),
                    geom.position)

                if geom.type == geom.BOX:
                    assert geom.num_float_data == 3

                    # Draw a bounding box.
                    patch = np.vstack((
                        geom.float_data[0]/2.*np.array([1, 1, 1, 1,
                                                        -1, -1, -1, -1]),
                        geom.float_data[1]/2.*np.array([1, 1, 1, 1,
                                                        -1, -1, -1, -1]),
                        geom.float_data[2]/2.*np.array([1, 1, -1, -1,
                                                        -1, -1, 1, 1])))

                elif geom.type == geom.SPHERE:
                    assert geom.num_float_data == 1
                    radius = geom.float_data[0]
                    sample_pts = np.arange(0., 2.*math.pi, 0.25)
                    patch = np.vstack([math.cos(pt)*self.Tview[0, 0:3]
                                       + math.sin(pt)*self.Tview[1, 0:3]
                                       for pt in sample_pts])
                    patch = np.transpose(patch)
                    patch *= radius

                elif geom.type == geom.CYLINDER:
                    assert geom.num_float_data == 2
                    radius = geom.float_data[0]
                    length = geom.float_data[1]

                    # In the lcm geometry, cylinders are along +z

                    # https://github.com/RobotLocomotion/drake/blob/last_sha_with_original_matlab/drake/matlab/systems/plants/RigidBodyCylinder.m

                    # I don't have access to the body to world transform
                    # yet; decide between drawing a box and circle assuming the
                    # T_body_to_world is will not rotate us out of the
                    # viewing plane.
                    z_axis = np.matmul(self.Tview[0:2, 0:3],
                                       element_local_tf.multiply([0, 0, 1]))
                    if np.linalg.norm(z_axis) < 0.01:
                        # Draw a circle.
                        sample_pts = np.arange(0., 2.*math.pi, 0.25)
                        patch = np.vstack([math.cos(pt)*self.Tview[0, 0:3]
                                           + math.sin(pt)*self.Tview[1, 0:3]
                                           for pt in sample_pts])
                        patch = np.transpose(patch)
                        patch *= radius
                    else:
                        # Draw a bounding box.
                        patch = np.vstack((
                            radius*np.array([1, 1, 1, 1, -1, -1, -1, -1]),
                            radius*np.array([1, 1, 1, 1, -1, -1, -1, -1]),
                            (length/2)*np.array([1, 1, -1, -1, -1, -1, 1, 1])))

                else:
                    print("UNSUPPORTED GEOMETRY TYPE {} IGNORED".format(
                        geom.type))
                    continue

                patch = np.vstack((patch, np.ones((1, patch.shape[1]))))
                patch = np.dot(element_local_tf.GetAsMatrix4(), patch)
                # Project into 2D
                patch = np.dot(self.Tview, patch)

                # Close path if not closed
                if (patch[:, -1] != patch[:, 0]).any():
                    patch = np.hstack((patch, patch[:, 0][np.newaxis].T))

                this_body_patches.append(patch)
                if use_random_colors:
                    this_body_colors.append(this_color)
                else:
                    this_body_colors.append(geom.color)

            self.viewPatches[link.name] = this_body_patches
            self.viewPatchColors[link.name] = this_body_colors
コード例 #37
0
    def _build_body_patches(self, use_random_colors,
                            substitute_collocated_mesh_files):
        """
        Generates body patches. self._patch_Blist stores a list of patches for
        each body (starting at body id 1). A body patch is a list of all 3D
        vertices of a piece of visual geometry.
        """
        self._patch_Blist = {}
        self._patch_Blist_colors = {}

        mock_lcm = DrakeMockLcm()
        mock_lcm_subscriber = Subscriber(lcm=mock_lcm,
                                         channel="DRAKE_VIEWER_LOAD_ROBOT",
                                         lcm_type=lcmt_viewer_load_robot)
        # TODO(SeanCurtis-TRI): Use SceneGraph inspection instead of mocking
        # LCM and inspecting the generated message.
        DispatchLoadMessage(self._scene_graph, mock_lcm)
        mock_lcm.HandleSubscriptions(0)
        assert mock_lcm_subscriber.count > 0
        load_robot_msg = mock_lcm_subscriber.message

        # Spawn a random color generator, in case we need to pick random colors
        # for some bodies. Each body will be given a unique color when using
        # this random generator, with each visual element of the body colored
        # the same.
        color = iter(
            plt.cm.rainbow(np.linspace(0, 1, load_robot_msg.num_links)))

        for i in range(load_robot_msg.num_links):
            link = load_robot_msg.link[i]

            this_body_patches = []
            this_body_colors = []
            this_color = next(color)

            for j in range(link.num_geom):
                geom = link.geom[j]
                # MultibodyPlant currently sets alpha=0 to make collision
                # geometry "invisible".  Ignore those geometries here.
                if geom.color[3] == 0:
                    continue

                X_BG = RigidTransform(
                    RotationMatrix(Quaternion(geom.quaternion)), geom.position)

                if geom.type == geom.BOX:
                    assert geom.num_float_data == 3

                    # Draw a bounding box.
                    patch_G = np.vstack(
                        (geom.float_data[0] / 2. *
                         np.array([-1, -1, 1, 1, -1, -1, 1, 1]),
                         geom.float_data[1] / 2. *
                         np.array([-1, 1, -1, 1, -1, 1, -1, 1]),
                         geom.float_data[2] / 2. *
                         np.array([-1, -1, -1, -1, 1, 1, 1, 1])))

                elif geom.type == geom.SPHERE:
                    assert geom.num_float_data == 1
                    radius = geom.float_data[0]
                    lati, longi = np.meshgrid(np.arange(0., 2. * math.pi, 0.5),
                                              np.arange(0., 2. * math.pi, 0.5))
                    lati = lati.ravel()
                    longi = longi.ravel()
                    patch_G = np.vstack([
                        np.sin(lati) * np.cos(longi),
                        np.sin(lati) * np.sin(longi),
                        np.cos(lati)
                    ])
                    patch_G *= radius

                elif geom.type == geom.CYLINDER:
                    assert geom.num_float_data == 2
                    radius = geom.float_data[0]
                    length = geom.float_data[1]

                    # In the lcm geometry, cylinders are along +z
                    # https://github.com/RobotLocomotion/drake/blob/last_sha_with_original_matlab/drake/matlab/systems/plants/RigidBodyCylinder.m
                    # Two circles: one at bottom, one at top.
                    sample_pts = np.arange(0., 2. * math.pi, 0.25)
                    patch_G = np.hstack([
                        np.array([[
                            radius * math.cos(pt), radius * math.sin(pt),
                            -length / 2.
                        ],
                                  [
                                      radius * math.cos(pt),
                                      radius * math.sin(pt), length / 2.
                                  ]]).T for pt in sample_pts
                    ])

                elif geom.type == geom.MESH:
                    filename = geom.string_data
                    base, ext = os.path.splitext(filename)
                    if (ext.lower() is not ".obj") and \
                       substitute_collocated_mesh_files:
                        # Check for a co-located .obj file (case insensitive).
                        for f in glob.glob(base + '.*'):
                            if f[-4:].lower() == '.obj':
                                filename = f
                                break
                        if filename[-4:].lower() != '.obj':
                            raise RuntimeError("The given file " + filename +
                                               " is not "
                                               "supported and no alternate " +
                                               base + ".obj could be found.")
                    if not os.path.exists(filename):
                        raise FileNotFoundError(errno.ENOENT,
                                                os.strerror(errno.ENOENT),
                                                filename)
                    mesh = ReadObjToSurfaceMesh(filename)
                    patch_G = np.vstack([v.r_MV() for v in mesh.vertices()]).T

                else:
                    print("UNSUPPORTED GEOMETRY TYPE {} IGNORED".format(
                        geom.type))
                    continue

                # Compute pose in body.
                patch_B = X_BG @ patch_G

                # Close path if not closed.
                if (patch_B[:, -1] != patch_B[:, 0]).any():
                    patch_B = np.hstack((patch_B, patch_B[:, 0][np.newaxis].T))

                this_body_patches.append(patch_B)
                if use_random_colors:
                    this_body_colors.append(this_color)
                else:
                    this_body_colors.append(geom.color)

            self._patch_Blist[link.name] = this_body_patches
            self._patch_Blist_colors[link.name] = this_body_colors
コード例 #38
0
    def load(self):
        """
        Loads `meshcat` visualization elements.
        @pre The `scene_graph` used to construct this object must be part of a
        fully constructed diagram (e.g. via `DiagramBuilder.Build()`).
        """
        # TODO(russt): Declare an initialization event to publish this
        # pending resolution of #9842.

        # Intercept load message via mock LCM.
        mock_lcm = DrakeMockLcm()
        DispatchLoadMessage(self._scene_graph, mock_lcm)
        load_robot_msg = lcmt_viewer_load_robot.decode(
            mock_lcm.get_last_published_message("DRAKE_VIEWER_LOAD_ROBOT"))
        # Translate elements to `meshcat`.
        for i in range(load_robot_msg.num_links):
            link = load_robot_msg.link[i]
            [source_name, frame_name] = link.name.split("::")

            for j in range(link.num_geom):
                geom = link.geom[j]
                element_local_tf = RigidTransform(
                    RotationMatrix(Quaternion(geom.quaternion)),
                    geom.position).GetAsMatrix4()

                if geom.type == geom.BOX:
                    assert geom.num_float_data == 3
                    meshcat_geom = meshcat.geometry.Box(geom.float_data)
                elif geom.type == geom.SPHERE:
                    assert geom.num_float_data == 1
                    meshcat_geom = meshcat.geometry.Sphere(geom.float_data[0])
                elif geom.type == geom.CYLINDER:
                    assert geom.num_float_data == 2
                    meshcat_geom = meshcat.geometry.Cylinder(
                        geom.float_data[1], geom.float_data[0])
                    # In Drake, cylinders are along +z
                    # In meshcat, cylinders are along +y
                    # Rotate to fix this misalignment
                    extra_rotation = tf.rotation_matrix(
                        math.pi / 2., [1, 0, 0])
                    element_local_tf[0:3, 0:3] = \
                        element_local_tf[0:3, 0:3].dot(
                            extra_rotation[0:3, 0:3])
                elif geom.type == geom.MESH:
                    meshcat_geom = \
                        meshcat.geometry.ObjMeshGeometry.from_file(
                            geom.string_data[0:-3] + "obj")
                else:
                    print "UNSUPPORTED GEOMETRY TYPE ", \
                        geom.type, " IGNORED"
                    continue

                self.vis[self.prefix][source_name][str(link.robot_num)][
                    frame_name][str(j)]\
                    .set_object(meshcat_geom,
                                meshcat.geometry
                                .MeshLambertMaterial(
                                    color=Rgb2Hex(geom.color)))
                self.vis[self.prefix][source_name][str(
                    link.robot_num)][frame_name][str(j)].set_transform(
                        element_local_tf)