Esempio n. 1
0
    def on_timer(self, ev):
        millis_passed = int(100 * (self.model.t % 1))
        sec_passed = int(self.model.t % 60)
        min_passed = int(self.model.t // 60)

        self.hook.transform.reset()
        self.hook.transform = transforms.MatrixTransform()
        self.hook.transform.scale((self.hook_length, self.hook_height, 0.001))
        self.hook.transform.translate(
            [self.hook_length / 2.016 + self.scale * self.model.x, 0.0])
        self.hook.transform.translate(self.center)

        # Apply the necessary transformations to the rod
        self.rod.transform.reset()
        self.rod.transform.scale(
            (self.rod_width, self.scale * self.model.l, 0.0001))
        self.rod.transform.translate([0.0, self.scale * self.model.l / 2.0])
        self.rod.transform.rotate(np.rad2deg(self.model.theta), (0, 0, 1))
        self.rod.transform.translate([self.scale * self.model.x, 0.0])
        self.rod.transform.translate(self.center)

        # Update the timer with how long it's been
        self.text.text = '{:0>2d}:{:0>2d}.{:0>2d}'.format(
            min_passed, sec_passed, millis_passed)

        self.update()
        self.model.do_time_step()
Esempio n. 2
0
    def update(self, t, crazyflies):
        if len(self.cfs) == 0:
            verts, faces, normals, nothin = io.read_mesh(CF_MESH_PATH)
            for i, cf in enumerate(crazyflies):
                color = cf.ledRGB
                mesh = scene.visuals.Mesh(parent=self.view.scene,
                    vertices=verts, faces=faces,
                    color=color, shading='smooth')
                mesh.transform = transforms.MatrixTransform()
                self.cfs.append(mesh)
                self.color_cache.append(color)

        for i in range(0, len(self.cfs)):
            x, y, z = crazyflies[i].position()
            roll, pitch, yaw = crazyflies[i].rpy()
            self.cfs[i].transform.reset()
            self.cfs[i].transform.rotate(90, (1, 0, 0))
            self.cfs[i].transform.rotate(math.degrees(roll), (1, 0, 0))
            self.cfs[i].transform.rotate(math.degrees(pitch), (0, 1, 0))
            self.cfs[i].transform.rotate(math.degrees(yaw), (0, 0, 1))
            self.cfs[i].transform.scale((0.001, 0.001, 0.001))
            self.cfs[i].transform.translate((x, y, z))
            # vispy does not do this check
            color = crazyflies[i].ledRGB
            if color != self.color_cache[i]:
                self.color_cache[i] = color
                self.cfs[i].color = color # sets dirty flag

        self.canvas.app.process_events()
Esempio n. 3
0
def add_mesh_data_to_view(mdata,
                          view,
                          want_faces=True,
                          want_points=True,
                          want_lines=True,
                          transform=transforms.MatrixTransform()):
  color = mdata.get('color', 'g')
  if isinstance(color, str) and color == 'random': color = np.random.random(3).tolist()
  else: color = Color(color).rgb.tolist()

  res = Attributize()
  res.lines = []
  res.objs = []
  if want_lines and 'lines' in mdata:
    for polyline in mdata.lines:
      if isinstance(polyline, Attributize):
        width = polyline.get('width', 1)
        method = 'gl'
        if width > 1: method = 'gl'
        l = Line(
            pos=np.array(np.array(polyline.polyline)),
            antialias=True,
            method=method,
            color=np.array(polyline.colors),
            width=width,)
      else:
        l = Line(pos=np.array(np.array(polyline)), antialias=False, method='gl', color=color)
      l.transform = transform
      view.add(l)
      res.lines.append(l)
      res.objs.append(l)

  if want_points and mdata.get('points', None) is not None:
    scatter = Markers()
    #mdata.points = np.array((
    #    (10.928140, -51.417831, -213.253723),
    #    (0.000000, -46.719570, -205.607208),
    #    (0.000000, -53.499737, -215.031876),
    #    (0.000000, -69.314308, -223.780746),
    #    (0.000000, -89.549263, -170.910568),))
    #mdata.points = np.array(((-12.138942,-55.812309,-217.007050),(10.928140,-51.417831,-213.253723),(-7.289741,-43.585541,-200.506531)))
    points_color = mdata.get('points_color', color)
    points_size = mdata.get('points_size', 10)
    points = np.array(mdata.points)

    #print('PLOTTING ', points, points_size)
    if len(points) == 0: return
    scatter.set_data(points, edge_color=None, face_color=points_color, size=points_size)
    scatter.transform = transform
    view.add(scatter)
    res.objs.append(scatter)
    res.points = scatter

  if want_faces and 'mesh' in mdata:
    mesh = Mesh(meshdata=mdata.mesh, color=color + [0.7])
    mesh.transform = transform
    view.add(mesh)
    res.mesh = mesh
    res.objs.append(mesh)
  return res
Esempio n. 4
0
 def __init__(self, rank, which_pos, how_many_seg, to_scale):
     super().__init__(radius=0.075
             , method='latitude'
             , color=(1, 0, 0, 0.5) if rank > 50 else (1, 1, 1, 0.5)
             )
     self.transform = transforms.MatrixTransform()
     self.transform.translate( to_scale * (which_pos - how_many_seg//2))
Esempio n. 5
0
    def __init__(self, view, radius, face_color, edge_color):
        super(mbSphere, self).__init__(radius,
                                       color=face_color,
                                       edge_color=edge_color,
                                       parent=view,
                                       method='ico')

        self.transform = transforms.MatrixTransform()
Esempio n. 6
0
    def __init__(self):
        app.Canvas.__init__(self, 'Cube', keys='interactive', size=(400, 400))

        self.cube = BoxVisual(1.0, 0.5, 0.25, color='red', edge_color='black')
        self.cube.transform = transforms.MatrixTransform()
        self.cube.transform.scale((100, 100, 0.001))
        self.cube.transform.translate((200, 200))

        self.quaternion = Quaternion()
        self.show()
Esempio n. 7
0
    def __init__(self, *args, **kwargs):
        self.cube = CubeVisual(size=(0.8, 0.5, 0.5),
                               color='red',
                               edge_color="k")
        self.theta = 0
        self.phi = 0
        self.cube_transform = transforms.MatrixTransform()
        self.cube.transform = self.cube_transform

        self._timer = Timer('auto', connect=self.on_timer, start=True)
        SceneCanvas.__init__(self, *args, **kwargs)
Esempio n. 8
0
 def _define_transformation(self):
     sh = self._sh
     r90 = vist.MatrixTransform()
     r90.rotate(90, (0, 0, 1))
     rx180 = vist.MatrixTransform()
     rx180.rotate(180, (1, 0, 0))
     # Sagittal transformation :
     norm_sagit = vist.STTransform(scale=(1. / sh[1], 1. / sh[2], 1.),
                                   translate=(-1., 0., 0.))
     tf_sagit = vist.ChainTransform([norm_sagit, r90, rx180])
     self._im_sagit.transform = tf_sagit
     # Coronal transformation :
     norm_coron = vist.STTransform(scale=(1. / sh[0], 1. / sh[2], 1.),
                                   translate=(0., 0., 0.))
     tf_coron = vist.ChainTransform([norm_coron, r90, rx180])
     self._im_coron.transform = tf_coron
     # Axial transformation :
     norm_axis = vist.STTransform(scale=(2. / sh[1], 2. / sh[0], 1.),
                                  translate=(-1., 0., 0.))
     tf_axial = vist.ChainTransform([norm_axis, rx180])
     self._im_axial.transform = tf_axial
Esempio n. 9
0
    def __init__(self, tensor_data):
        self.canvas = CostumizedCanvas(keys='interactive')
        self.view = self.canvas.central_widget.add_view()
        self.view.camera = 'turntable'
        #self.view.camera = 'fly'
        self.canvas.central_widget.remove_widget(self.view)
        self.canvas.central_widget.add_widget(self.view)
        tensor_data.register(self)

        self.axis = scene.visuals.XYZAxis(parent=self.view.scene)
        self.axis.transform = transforms.MatrixTransform()
        self.axis.transform.translate((-1, -1, -1))
        self.shower_units = []
Esempio n. 10
0
def test_st_transform():
    # Check that STTransform maps exactly like MatrixTransform
    pts = np.random.normal(size=(10, 4))

    scale = (1, 7.5, -4e-8)
    translate = (1e6, 0.2, 0)
    st = tr.STTransform(scale=scale, translate=translate)
    at = tr.MatrixTransform()
    at.scale(scale)
    at.translate(translate)

    assert np.allclose(st.map(pts), at.map(pts))
    assert np.allclose(st.inverse.map(pts), at.inverse.map(pts))
Esempio n. 11
0
 def __init__(self, parent=None):
     """Init."""
     # Add PanZoom cameras to each box :
     parent['Sagit'].camera = scene.PanZoomCamera()
     parent['Coron'].camera = scene.PanZoomCamera()
     parent['Axial'].camera = scene.PanZoomCamera()
     # Define three images (Sagittal, Coronal, Axial) :
     kwargs_im = {'interpolation': 'bilinear'}
     self._cspSagit = visu.Image(name='SagitSplit', **kwargs_im)
     self._cspCoron = visu.Image(name='CoronSplit', **kwargs_im)
     self._cspAxial = visu.Image(name='AxialSplit', **kwargs_im)
     # Define three text object :
     kwargs_txt = {
         'color': 'white',
         'font_size': 2,
         'anchor_x': 'left',
         'anchor_y': 'bottom'
     }
     self._cspTxtSagit = visu.Text(text='Sagit', **kwargs_txt)
     self._cspTxtCoron = visu.Text(text='Coron', **kwargs_txt)
     self._cspTxtAxial = visu.Text(text='Axial', **kwargs_txt)
     # Add each image to parent :
     parent['Sagit'].add(self._cspSagit)
     parent['Coron'].add(self._cspCoron)
     parent['Axial'].add(self._cspAxial)
     # Add text to parent :
     parent['Sagit'].add(self._cspTxtSagit)
     parent['Coron'].add(self._cspTxtCoron)
     parent['Axial'].add(self._cspTxtAxial)
     # Add transformations :
     r90 = vist.MatrixTransform()
     r90.rotate(90, (0, 0, 1))
     r180 = vist.MatrixTransform()
     r180.rotate(180, (0, 0, 1))
     self._cspSagit.transform = r90
     self._cspCoron.transform = r90
     self._cspAxial.transform = r180
     self._parent_sp = parent
Esempio n. 12
0
    def __init__(self):
        app.Canvas.__init__(self, 'Cube', keys='interactive', size=(400, 400))

        self.cube = BoxVisual(1.0, 0.5, 0.25, color='red', edge_color="k")
        self.theta = 0
        self.phi = 0

        # Create a TransformSystem that will tell the visual how to draw
        self.cube_transform = transforms.MatrixTransform()
        self.cube.transform = self.cube_transform

        self._timer = app.Timer('auto', connect=self.on_timer, start=True)

        self.show()
Esempio n. 13
0
    def __init__(self, connection, orientation):
        self.con = connection
        self.orientation = orientation
        app.Canvas.__init__(self, 'Cube', keys='interactive', size=(400, 400))
        self.cube = CubeVisual((7.0, 4.0, 0.3),
                               color=Color(color='grey', alpha=0.1,
                                           clip=False),
                               edge_color="black")

        # Create a TransformSystem that will tell the visual how to draw
        self.cube_transform = transforms.MatrixTransform()
        self.cube.transform = self.cube_transform
        self._timer = app.Timer('0.05', connect=self.on_timer, start=True)
        self.show()
Esempio n. 14
0
    def update(self, t, crazyflies):
        if len(self.cfs) == 0:
            verts, faces, normals, nothin = io.read_mesh(CF_MESH_PATH)
            for i, cf in enumerate(crazyflies):
                color = cf.ledRGB
                mesh = scene.visuals.Mesh(
                    parent=self.view.scene,
                    vertices=verts,
                    faces=faces,
                    color=color,
                    shading="smooth",
                )
                mesh.light_dir = (0.1, 0.1, 1.0)
                mesh.shininess = 0.01
                mesh.ambient_light_color = [0.5] * 3
                mesh.transform = transforms.MatrixTransform()
                self.cfs.append(mesh)
                self.color_cache.append(color)

        positions = np.stack(cf.position() for cf in crazyflies)

        for i in range(0, len(self.cfs)):
            x, y, z = crazyflies[i].position()
            roll, pitch, yaw = crazyflies[i].rpy()
            self.cfs[i].transform.reset()
            self.cfs[i].transform.rotate(-90, (1, 0, 0))
            self.cfs[i].transform.rotate(math.degrees(roll), (1, 0, 0))
            self.cfs[i].transform.rotate(math.degrees(pitch), (0, 1, 0))
            self.cfs[i].transform.rotate(math.degrees(yaw), (0, 0, 1))
            self.cfs[i].transform.scale((0.002, 0.002, -0.002))
            self.cfs[i].transform.translate(positions[i])
            # vispy does not do this check
            color = crazyflies[i].ledRGB
            if color != self.color_cache[i]:
                self.color_cache[i] = color
                self.cfs[i].color = color  # sets dirty flag

        # Update graph line segments to match new Crazyflie positions.
        if self.graph is not None:
            for k, (i, j) in enumerate(self.graph_edges):
                self.graph_lines[2 * k, :] = positions[i]
                self.graph_lines[2 * k + 1, :] = positions[j]
            self.graph.set_data(self.graph_lines)

        self.canvas.app.process_events()
Esempio n. 15
0
    def __init__(self, parent=None, parent_sp=None, visible=True, cmap='gray'):
        """Init."""
        CrossSectionsSplit.__init__(self, parent_sp)
        self._visible_cs = visible
        self._cmap_cs = cmap
        #######################################################################
        #                           TRANFORMATIONS
        #######################################################################
        # Translations :
        self._tr_coron = vist.STTransform()
        self._tr_sagit = vist.STTransform()
        self._tr_axial = vist.STTransform()
        # Rotations :
        rot_m90x = vist.MatrixTransform(rotate(-90, [1, 0, 0]))
        rot_180x = vist.MatrixTransform(rotate(180, [1, 0, 0]))
        rot_90y = vist.MatrixTransform(rotate(90, [0, 1, 0]))
        rot_m90y = vist.MatrixTransform(rotate(-90, [0, 1, 0]))
        rot_m180y = vist.MatrixTransform(rotate(-180, [0, 1, 0]))
        rot_90z = vist.MatrixTransform(rotate(90, [0, 0, 1]))
        # Tranformations :
        tf_sagit = [self._tr_sagit, rot_90z, rot_m90y, rot_m90x]
        tf_coron = [self._tr_coron, rot_90z, rot_180x, rot_90y]
        tf_axial = [self._tr_axial, rot_m180y, rot_90z]

        #######################################################################
        #                            ELEMENTS
        #######################################################################
        # Create a root node :
        self._node_cs = scene.Node(name='Cross-Sections')
        self._node_cs.parent = parent
        self._node_cs.visible = visible
        # Axial :
        self.axial = ImageSection(parent=self._node_cs, name='Axial')
        self.axial.transform = vist.ChainTransform(tf_axial)
        # Coronal :
        self.coron = ImageSection(parent=self._node_cs, name='Coronal')
        self.coron.transform = vist.ChainTransform(tf_coron)
        # Sagittal :
        self.sagit = ImageSection(parent=self._node_cs, name='Sagittal')
        self.sagit.transform = vist.ChainTransform(tf_sagit)
        # Set GL state :
        kwargs = {
            'depth_test': True,
            'cull_face': False,
            'blend': False,
            'blend_func': ('src_alpha', 'one_minus_src_alpha')
        }
        self.sagit.set_gl_state('translucent', **kwargs)
        self.coron.set_gl_state('translucent', **kwargs)
        self.axial.set_gl_state('translucent', **kwargs)
Esempio n. 16
0
 def __init__(self,
              view,
              radius,
              path,
              face_color,
              tube_points=16,
              closed=True):
     """
     points : ndarray
         An array of (x, y, z) points describing the path along which the
         tube will be extruded.
     radius : float
         The radius of the tube. Defaults to 1.0.
     closed : bool
         Whether the tube should be closed, joining the last point to the
         first. Defaults to False.
     color : Color | ColorArray
         The color(s) to use when drawing the tube. The same color is
         applied to each vertex of the mesh surrounding each point of
         the line. If the input is a ColorArray, the argument will be
         cycled; for instance if 'red' is passed then the entire tube
         will be red, or if ['green', 'blue'] is passed then the points
         will alternate between these colours. Defaults to 'purple'.
     tube_points : int
         The number of points in the circle-approximating polygon of the
         tube's cross section. Defaults to 8.
     shading : str | None
         Same as for the `MeshVisual` class. Defaults to 'smooth'.
     vertex_colors: ndarray | None
         Same as for the `MeshVisual` class.
     face_colors: ndarray | None
         Same as for the `MeshVisual` class.
     mode : str
         Same as for the `MeshVisual` class. Defaults to 'triangles'.
     """
     super(mbTube, self).__init__(radius=radius,
                                  points=path,
                                  color=face_color,
                                  tube_points=tube_points,
                                  closed=closed,
                                  parent=view)
     self.transform = transforms.MatrixTransform()
Esempio n. 17
0
def add_cubes():
    cm = get_colormap('hot')
    how_many_seg = 5
    for l in range(how_many_seg):
        for m in range(how_many_seg):
            for n in range(how_many_seg):
                cube_size = 0.15
                how_much_red = np.random.random()
                cube = scene.visuals.Sphere(
                          radius=cube_size/2
                        , method='latitude'
                        , color=cm[np.random.random()]
                        )
                #cube = scene.visuals.Cube((cube_size, cube_size, cube_size),
                        #color=ColorArray((how_much_red, 0, 0, 0.8)))#,
                        #edge_color='k')
                cube.transform = transforms.MatrixTransform()
                to_translate = 0.4
                cube.transform.translate((to_translate*(l-how_many_seg//2), to_translate*(m-how_many_seg//2), to_translate*(n-how_many_seg//2)))
                _context.view.add(cube)
Esempio n. 18
0
 def test_convert_meshdata(self):
     """Test convert_meshdata function."""
     from vispy.geometry import MeshData
     import vispy.visuals.transforms as vist
     # Force creation of vertices, faces and normals :
     self._creation()
     tup = (self.vertices, self.faces)
     # Compare (vertices + faces) Vs. MeshData :
     mesh1 = convert_meshdata(*tup)
     mesh2 = convert_meshdata(meshdata=MeshData(*tup))
     assert np.array_equal(mesh1[0], mesh2[0])
     assert np.array_equal(mesh1[1], mesh2[1])
     assert np.array_equal(mesh1[2], mesh2[2])
     # Invert normals :
     inv1 = convert_meshdata(*tup, invert_normals=True)[-1]
     assert np.array_equal(inv1, -mesh1[-1])
     # Create transformation :
     tr = vist.MatrixTransform()
     tr.rotate(90, (0, 0, 1))
     convert_meshdata(*tup, transform=tr)[-1]
Esempio n. 19
0
 def __init__(self,
              name,
              vol,
              transform=None,
              roi_values=None,
              roi_labels=None):
     """Init."""
     #######################################################################
     #                               CHECK DATA
     #######################################################################
     # Name :
     if isinstance(name, str):
         self.name = name
     else:
         raise ValueError("The name variable must be a string.")
     # Volume :
     if isinstance(vol, np.ndarray) and (vol.ndim == 3):
         self.vol = vol
     else:
         raise ValueError("The vol variable must be 3-D array.")
     # Transformation :
     if not isinstance(transform, vist.MatrixTransform):
         self.transform = vist.MatrixTransform()
     else:
         self.transform = transform
     # Index and label :
     if isinstance(roi_values, np.ndarray) and isinstance(
             roi_labels, np.ndarray):
         self._is_roi = len(roi_labels) == len(roi_values)
     else:
         self._is_roi = False
     self.roi_values = roi_values
     self.roi_labels = roi_labels
     # Get (nx, ny, nz) and minmax :
     self._sh = vol.shape
     self._nx, self._ny, self._nz = np.array(self._sh) - 1
     self._minmax = (vol.min(), vol.max())
     self._clim = self._minmax
Esempio n. 20
0
def test_affine_mapping():
    t = tr.MatrixTransform()
    p1 = np.array([[0, 0, 0], [1, 0, 0], [0, 1, 0], [0, 0, 1]])

    # test pure translation
    p2 = p1 + 5.5
    t.set_mapping(p1, p2)
    assert np.allclose(t.map(p1)[:, :p2.shape[1]], p2)

    # test pure scaling
    p2 = p1 * 5.5
    t.set_mapping(p1, p2)
    assert np.allclose(t.map(p1)[:, :p2.shape[1]], p2)

    # test scale + translate
    p2 = (p1 * 5.5) + 3.5
    t.set_mapping(p1, p2)
    assert np.allclose(t.map(p1)[:, :p2.shape[1]], p2)

    # test SRT
    p2 = np.array([[10, 5, 3], [10, 15, 3], [30, 5, 3], [10, 5, 3.5]])
    t.set_mapping(p1, p2)
    assert np.allclose(t.map(p1)[:, :p2.shape[1]], p2)
Esempio n. 21
0
    def update(self, t, crazyflies):
        if len(self.cfs) == 0:
            verts, faces, normals, nothin = io.read_mesh(
                os.path.join(os.path.dirname(__file__), "crazyflie2.obj.gz"))
            for i in range(0, len(crazyflies)):
                mesh = scene.visuals.Mesh(vertices=verts,
                                          shading='smooth',
                                          faces=faces,
                                          parent=self.view.scene)
                mesh.transform = transforms.MatrixTransform()
                self.cfs.append(mesh)

        for i in range(0, len(self.cfs)):
            x, y, z = crazyflies[i].position()
            roll, pitch, yaw = crazyflies[i].rpy()
            self.cfs[i].transform.reset()
            self.cfs[i].transform.rotate(90, (1, 0, 0))
            self.cfs[i].transform.rotate(math.degrees(roll), (1, 0, 0))
            self.cfs[i].transform.rotate(math.degrees(pitch), (0, 1, 0))
            self.cfs[i].transform.rotate(math.degrees(yaw), (0, 0, 1))
            self.cfs[i].transform.scale((0.001, 0.001, 0.001))
            self.cfs[i].transform.translate((x, y, z))

        self.canvas.app.process_events()
Esempio n. 22
0
    def on_timer(self, ev):
        millis_passed = int(100 * (self.model.t % 1))
        sec_passed = int(self.model.t % 60)
        min_passed = int(self.model.t // 60)

        self.rear_wheelsL.transform.reset()
        self.rear_wheelsL.transform.scale((self.scale*2.0, self.scale*0.5, 1))
        self.rear_wheelsL.transform.translate([0.0, -self.scale*0.5*4.0])
        self.rear_wheelsL.transform.rotate(np.rad2deg(-self.model.theta), (0, 0, 1))
        self.rear_wheelsL.transform.translate([self.model.x, self.model.y])
        self.rear_wheelsL.transform.translate(self.center)

        self.rear_wheelsR.transform.reset()
        self.rear_wheelsR.transform.scale((self.scale*2.0, self.scale*0.5, 1))
        self.rear_wheelsR.transform.translate([0.0, self.scale*0.5*4.0])
        self.rear_wheelsR.transform.rotate(np.rad2deg(-self.model.theta), (0, 0, 1))
        self.rear_wheelsR.transform.translate([self.model.x, self.model.y])
        self.rear_wheelsR.transform.translate(self.center)

        self.front_wheelsL.transform.reset()
        self.front_wheelsL.transform.scale((self.scale*2.0, self.scale*0.5, 1))
        self.front_wheelsL.transform.rotate(np.rad2deg(-self.model.fi), (0, 0, 1))
        self.front_wheelsL.transform.translate([self.scale*self.model.l, -self.scale*0.5*4.0])
        self.front_wheelsL.transform.rotate(np.rad2deg(-self.model.theta), (0, 0, 1))
        self.front_wheelsL.transform.translate([self.model.x, self.model.y])
        self.front_wheelsL.transform.translate(self.center)

        self.front_wheelsR.transform.reset()
        self.front_wheelsR.transform.scale((self.scale*2.0, self.scale*0.5, 1))
        self.front_wheelsR.transform.rotate(np.rad2deg(-self.model.fi), (0, 0, 1))
        self.front_wheelsR.transform.translate([self.scale*self.model.l, self.scale*0.5*4.0])
        self.front_wheelsR.transform.rotate(np.rad2deg(-self.model.theta), (0, 0, 1))
        self.front_wheelsR.transform.translate([self.model.x, self.model.y])
        self.front_wheelsR.transform.translate(self.center)

        # Apply the necessary transformations to the vehicle_body
        self.vehicle_body.transform.reset()
        self.vehicle_body.transform.translate([0.5, 0.0])
        self.vehicle_body.transform.scale((self.scale*self.model.l, self.scale, 1))
        self.vehicle_body.transform.rotate(np.rad2deg(-self.model.theta), (0, 0, 1))
        self.vehicle_body.transform.translate([self.model.x, self.model.y])
        self.vehicle_body.transform.translate(self.center)

        self.vehicle_bodyF.transform.reset()
        self.vehicle_bodyF.transform.scale((self.scale*0.25, self.scale*4.0, 1))
        self.vehicle_bodyF.transform.translate([self.model.l*self.scale, 0.0])
        self.vehicle_bodyF.transform.rotate(np.rad2deg(-self.model.theta), (0, 0, 1))
        self.vehicle_bodyF.transform.translate([self.model.x, self.model.y])
        self.vehicle_bodyF.transform.translate(self.center)

        self.vehicle_bodyR.transform.reset()
        self.vehicle_bodyR.transform = transforms.MatrixTransform()
        self.vehicle_bodyR.transform.scale((self.scale*0.25, self.scale*4.0, 1))
        self.vehicle_bodyR.transform.rotate(np.rad2deg(-self.model.theta), (0, 0, 1))
        self.vehicle_bodyR.transform.translate([self.model.x, self.model.y])
        self.vehicle_bodyR.transform.translate(self.center)

        # Update the timer with how long it's been
        self.text.text = '{:0>2d}:{:0>2d}.{:0>2d}'.format(min_passed,
                                                          sec_passed,
                                                          millis_passed)

        self.update()
        self.model.do_time_step()
Esempio n. 23
0
 def __init__(self, view, a, b, c, face_color, edge_color):
     super(mbCube, self).__init__((a, b, c),
                                  color=face_color,
                                  edge_color=edge_color,
                                  parent=view)
     self.transform = transforms.MatrixTransform()
Esempio n. 24
0
        if it is not a pure scaling transform
    '''

    assert isinstance(
        M, transforms.MatrixTransform), "need MatrixTransform object"
    # scaling, rotation, shear happens in the top left 3x3 matrix
    R = np.array(M.matrix)[:3, :3]
    if not is_diag(R):
        # issue warning that it is not pure scale + translate
        return None
    # scaling information is just the diagonal
    return np.diag(R)


if __name__ == "__main__":
    transform = transforms.MatrixTransform()
    print("after instantiation")
    print("scale: ", get_scale_from_MatrixTransform(transform))
    print("translate: ", get_translation_from_MatrixTransform(transform))

    transform.scale((99.0, 11.0, 1.1))
    transform.translate((200, 100))
    print("After scale and translate")
    print("scale: ", get_scale_from_MatrixTransform(transform))
    print("translate: ", get_translation_from_MatrixTransform(transform))

    transform.rotate(33.0, (0.5, 1.0, 1.0))
    print("After rotate")
    print("scale: ", get_scale_from_MatrixTransform(transform))
    print("translate: ", get_translation_from_MatrixTransform(transform))
Esempio n. 25
0
    def update(self, t, crazyflies):
        if len(self.cfs) == 0:
            verts, faces, normals, nothin = io.read_mesh(CF_MESH_PATH)
            for i, cf in enumerate(crazyflies):
                color = cf.ledRGB
                mesh = scene.visuals.Mesh(
                    parent=self.view.scene,
                    vertices=verts,
                    faces=faces,
                    color=color,
                    shading="smooth",
                )
                mesh.light_dir = (0.1, 0.1, 1.0)
                mesh.shininess = 0.01
                mesh.ambient_light_color = [0.5] * 3
                mesh.transform = transforms.MatrixTransform()
                self.cfs.append(mesh)
                self.led_color_cache.append(color)

        if self.ellipsoid_radii is not None and self.ellipsoids is None:
            sphere_mesh = geometry.create_sphere(radius=1.0)
            self.ellipsoids = [
                scene.visuals.Mesh(
                    parent=self.view.scene,
                    meshdata=sphere_mesh,
                    color=ELLIPSOID_COLOR_OK,
                    shading="smooth",
                ) for _ in self.cfs
            ]
            for ell in self.ellipsoids:
                ell.light_dir = (0.1, 0.1, 1.0)
                ell.shininess = 0.0
                ell.ambient_light_color = [0.5] * 3
                ell.transform = transforms.MatrixTransform()

        positions = np.stack([cf.position() for cf in crazyflies])

        for i in range(0, len(self.cfs)):
            x, y, z = crazyflies[i].position()
            roll, pitch, yaw = crazyflies[i].rpy()
            self.cfs[i].transform.reset()
            self.cfs[i].transform.rotate(-90, (1, 0, 0))
            self.cfs[i].transform.rotate(math.degrees(roll), (1, 0, 0))
            self.cfs[i].transform.rotate(math.degrees(pitch), (0, 1, 0))
            self.cfs[i].transform.rotate(math.degrees(yaw), (0, 0, 1))
            self.cfs[i].transform.scale((0.002, 0.002, -0.002))
            self.cfs[i].transform.translate(positions[i])
            # vispy does not do this check
            color = crazyflies[i].ledRGB
            if color != self.led_color_cache[i]:
                self.led_color_cache[i] = color
                self.cfs[i].color = color  # sets dirty flag

        # Update graph line segments to match new Crazyflie positions.
        if self.graph is not None:
            for k, (i, j) in enumerate(self.graph_edges):
                self.graph_lines[2 * k, :] = positions[i]
                self.graph_lines[2 * k + 1, :] = positions[j]
            self.graph.set_data(self.graph_lines)

        # Update collsiion ellipsoids.
        if self.ellipsoids is not None:
            colliding = util.check_ellipsoid_collisions(
                positions, self.ellipsoid_radii)
            for i, pos in enumerate(positions):
                ell = self.ellipsoids[i]
                tf = ell.transform
                tf.reset()
                tf.scale(self.ellipsoid_radii)
                tf.translate(pos)
                new_color = ELLIPSOID_COLOR_COLLISION if colliding[
                    i] else ELLIPSOID_COLOR_OK
                if not (new_color
                        == ell.color):  # vispy Color lacks != override.
                    ell.color = new_color

        self.canvas.app.process_events()
Esempio n. 26
0
    def update(self, t, crazyflies, spheres=[], obstacles=[], crumb=None):
        if len(self.cfs
               ) == 0:  # add the crazyflies if they don't exist already
            verts, faces, normals, nothin = io.read_mesh(
                os.path.join(os.path.dirname(__file__), "crazyflie2.obj.gz"))
            for i in range(0, len(crazyflies)):
                mesh = scene.visuals.Mesh(vertices=verts,
                                          shading='smooth',
                                          faces=faces,
                                          parent=self.view.scene)
                mesh.transform = transforms.MatrixTransform()
                self.cfs.append(mesh)

        if crumb is not None:  # add breadcrumb trails behind drones if requested.
            if len(self.crumbs) == 0 or np.linalg.norm(self.crumbs[-1] -
                                                       crumb) > 0.05:
                # Only add them if drone is sufficiently far from the last breakcrumb.
                self.crumbs.append(crumb)
                self.markers.set_data(np.array(self.crumbs),
                                      size=5,
                                      face_color='black',
                                      edge_color='black')
        elif self.crumbs:
            self.markers.set_data(np.array([[1e10, 1e10]]))
            self.crumbs = []

        if spheres:  # sphere: (position, color)
            if not self.spheres:
                for pos, color in spheres:
                    self.spheres.append(
                        scene.visuals.Sphere(radius=.02,
                                             color=color,
                                             parent=self.view.scene))
                    self.spheres[-1].transform = transforms.STTransform(
                        translate=pos)
            for i, (pos, color) in enumerate(spheres):
                self.spheres[i].transform.translate = pos

        if obstacles:  # cube : (position, size)
            if not self.obstacles:
                for pos, size, _ in obstacles:
                    self.obstacles.append(
                        scene.visuals.Cube(size=size,
                                           color=random.choice(
                                               get_color_names()),
                                           parent=self.view.scene))
                    self.obstacles[-1].transform = transforms.STTransform(
                        translate=pos)
            for i, (pos, size, _) in enumerate(obstacles):
                self.obstacles[i].transform.translate = pos

        # update the location of the crazyflies if they have changed
        for i in range(0, len(self.cfs)):
            x, y, z = crazyflies[i].position(t)
            roll, pitch, yaw = crazyflies[i].rpy(t)
            self.cfs[i].transform.reset()
            self.cfs[i].transform.rotate(90, (1, 0, 0))
            self.cfs[i].transform.rotate(math.degrees(roll), (1, 0, 0))
            self.cfs[i].transform.rotate(math.degrees(pitch), (0, 1, 0))
            self.cfs[i].transform.rotate(math.degrees(yaw), (0, 0, 1))
            self.cfs[i].transform.scale((0.001, 0.001, 0.001))
            self.cfs[i].transform.translate((x, y, z))

        self.canvas.app.process_events()  # redraw the canvas
Esempio n. 27
0
    def __init__(self, list_of_charts, theta, omega, g, m, kp, kd, l, scale,
                 method, control, save_charts, dt, tmax, font_size):

        VisualModel.__init__(self)

        self.model = PendulumModel(list_of_charts)
        self.list_of_charts = list_of_charts

        self.vis_length = l

        self._set_up_system(l=l,
                            g=g,
                            m=m,
                            theta=theta,
                            omega=omega,
                            kp=kp,
                            kd=kd,
                            scale=scale,
                            method=method,
                            control=control,
                            save_charts=save_charts,
                            dt=dt,
                            tmax=tmax,
                            font_size=font_size)

        # Put up a text visual to display time info
        self.font_size = 24. if font_size is None else font_size
        self.text = visuals.TextVisual('0:00.00',
                                       color='white',
                                       pos=[15, 50, 0],
                                       anchor_x='left',
                                       anchor_y='bottom')
        self.text.font_size = self.font_size

        self.params = []
        self.params.append(
            visuals.TextVisual('td',
                               color='white',
                               pos=[15, 80, 0],
                               anchor_x='left',
                               anchor_y='bottom'))
        self.params.append(
            visuals.TextVisual('tr_1090',
                               color='white',
                               pos=[15, 100, 0],
                               anchor_x='left',
                               anchor_y='bottom'))
        self.params.append(
            visuals.TextVisual('tr_0595',
                               color='white',
                               pos=[15, 120, 0],
                               anchor_x='left',
                               anchor_y='bottom'))
        self.params.append(
            visuals.TextVisual('tr_0100',
                               color='white',
                               pos=[15, 140, 0],
                               anchor_x='left',
                               anchor_y='bottom'))
        self.params.append(
            visuals.TextVisual('tp',
                               color='white',
                               pos=[15, 160, 0],
                               anchor_x='left',
                               anchor_y='bottom'))
        self.params.append(
            visuals.TextVisual('over',
                               color='white',
                               pos=[15, 180, 0],
                               anchor_x='left',
                               anchor_y='bottom'))
        self.params.append(
            visuals.TextVisual('ts_2',
                               color='white',
                               pos=[15, 200, 0],
                               anchor_x='left',
                               anchor_y='bottom'))
        self.params.append(
            visuals.TextVisual('ts_5',
                               color='white',
                               pos=[15, 220, 0],
                               anchor_x='left',
                               anchor_y='bottom'))
        for param in self.params:
            param.font_size = 12

        self.hook = visuals.BoxVisual(width=0.25,
                                      height=0.25,
                                      depth=0.25,
                                      color='grey')
        self.hook.transform = transforms.MatrixTransform()
        self.hook.transform.scale(
            (self.scale * self.model.l, self.scale * self.model.l, 0.0001))
        self.hook.transform.translate(self.center)

        self.rod = visuals.BoxVisual(width=self.vis_length / 40,
                                     height=self.vis_length / 40,
                                     depth=self.vis_length,
                                     color='green')
        self.rod.transform = transforms.MatrixTransform()
        self.rod.transform.translate([0.0, self.vis_length / 2.0])
        self.rod.transform.scale(
            (self.scale * self.model.l, self.scale * self.model.l, 0.0001))
        self.rod.transform.rotate(np.rad2deg(self.model.theta), (0, 0, 1))
        self.rod.transform.translate(self.center)

        # Append all the visuals
        self.visuals.append(self.rod)
        self.visuals.append(self.hook)
        self.visuals.append(self.text)
        for param in self.params:
            self.visuals.append(param)
Esempio n. 28
0
    def __init__(self, list_of_charts, theta, fi, kp, kd,
                 l, scale, x, y, method, control, save_charts,
                 dt, tmax, font_size):

        VisualModel.__init__(self)

        self.center = [400, 400]
        self.model = VehicleKinematicModel(list_of_charts)
        self.list_of_charts = list_of_charts

        self._set_up_system(
            l=l, theta=theta, fi=fi, x=x, y=y, kp=kp,
            kd=kd, scale=scale, method=method, control=control,
            save_charts=save_charts, dt=dt, tmax=tmax, font_size=font_size
        )

        # Put up a text visual to display time info
        self.font_size = 24. if font_size is None else font_size
        self.text = visuals.TextVisual('0:00.00',
                                       color='white',
                                       pos=[15, 50, 0],
                                       anchor_x='left',
                                       anchor_y='bottom')
        self.text.font_size = self.font_size

        self.rear_wheelsL = visuals.BoxVisual(width=1.0, height=1.0, depth=1.0,
                                              color='yellow')
        self.rear_wheelsL.transform = transforms.MatrixTransform()
        self.rear_wheelsL.transform.scale((self.scale*2.0, self.scale*0.5, 1))
        self.rear_wheelsL.transform.translate([0.0, -self.scale*0.5*4.0])
        self.rear_wheelsL.transform.rotate(np.rad2deg(-self.model.theta), (0, 0, 1))
        self.rear_wheelsL.transform.translate([self.model.x, self.model.y])
        self.rear_wheelsL.transform.translate(self.center)

        self.rear_wheelsR = visuals.BoxVisual(width=1.0, height=1.0, depth=1.0,
                                              color='yellow')
        self.rear_wheelsR.transform = transforms.MatrixTransform()
        self.rear_wheelsR.transform.scale((self.scale*2.0, self.scale*0.5, 1))
        self.rear_wheelsR.transform.translate([0.0, self.scale*0.5*4.0])
        self.rear_wheelsR.transform.rotate(np.rad2deg(-self.model.theta), (0, 0, 1))
        self.rear_wheelsR.transform.translate([self.model.x, self.model.y])
        self.rear_wheelsR.transform.translate(self.center)

        self.front_wheelsL = visuals.BoxVisual(width=1.0, height=1.0, depth=1.0,
                                              color='pink')
        self.front_wheelsL.transform = transforms.MatrixTransform()
        self.front_wheelsL.transform.scale((self.scale*2.0, self.scale*0.5, 1))
        self.front_wheelsL.transform.rotate(np.rad2deg(-self.model.fi), (0, 0, 1))
        self.front_wheelsL.transform.translate([self.scale*l, -self.scale*0.5*4.0])
        self.front_wheelsL.transform.rotate(np.rad2deg(-self.model.theta), (0, 0, 1))
        self.front_wheelsL.transform.translate([self.model.x, self.model.y])
        self.front_wheelsL.transform.translate(self.center)

        self.front_wheelsR = visuals.BoxVisual(width=1.0, height=1.0, depth=1.0,
                                              color='pink')
        self.front_wheelsR.transform = transforms.MatrixTransform()
        self.front_wheelsR.transform.scale((self.scale*2.0, self.scale*0.5, 1))
        self.front_wheelsR.transform.rotate(np.rad2deg(-self.model.fi), (0, 0, 1))
        self.front_wheelsR.transform.translate([self.scale*l, self.scale*0.5*4.0])
        self.front_wheelsR.transform.rotate(np.rad2deg(-self.model.theta), (0, 0, 1))
        self.front_wheelsR.transform.translate([self.model.x, self.model.y])
        self.front_wheelsR.transform.translate(self.center)

        self.vehicle_body = visuals.BoxVisual(width=1.0, height=1.0, depth=1.0,
                                              color='green')
        self.vehicle_body.transform = transforms.MatrixTransform()
        self.vehicle_body.transform.translate([0.5, 0.0])
        self.vehicle_body.transform.scale((self.scale*self.model.l, self.scale, 1))
        self.vehicle_body.transform.rotate(np.rad2deg(-self.model.theta), (0, 0, 1))
        self.vehicle_body.transform.translate([self.model.x, self.model.y])
        self.vehicle_body.transform.translate(self.center)

        self.vehicle_bodyF = visuals.BoxVisual(width=1.0, height=1.0, depth=1.0,
                                              color='red')
        self.vehicle_bodyF.transform = transforms.MatrixTransform()
        self.vehicle_bodyF.transform.scale((self.scale*0.25, self.scale*4.0, 1))
        self.vehicle_bodyF.transform.translate([l*self.scale, 0.0])
        self.vehicle_bodyF.transform.rotate(np.rad2deg(-self.model.theta), (0, 0, 1))
        self.vehicle_bodyF.transform.translate([self.model.x, self.model.y])
        self.vehicle_bodyF.transform.translate(self.center)

        self.vehicle_bodyR = visuals.BoxVisual(width=1.0, height=1.0, depth=1.0,
                                              color='blue')
        self.vehicle_bodyR.transform = transforms.MatrixTransform()
        self.vehicle_bodyR.transform.scale((self.scale*0.25, self.scale*4.0, 1))
        self.vehicle_bodyR.transform.rotate(np.rad2deg(-self.model.theta), (0, 0, 1))
        self.vehicle_bodyR.transform.translate([self.model.x, self.model.y])
        self.vehicle_bodyR.transform.translate(self.center)

        # Append all the visuals
        self.visuals.append(self.vehicle_body)
        self.visuals.append(self.vehicle_bodyF)
        self.visuals.append(self.vehicle_bodyR)
        self.visuals.append(self.rear_wheelsL)
        self.visuals.append(self.rear_wheelsR)
        self.visuals.append(self.front_wheelsL)
        self.visuals.append(self.front_wheelsR)
        self.visuals.append(self.text)
Esempio n. 29
0
    def __init__(self,
                 d1=None,
                 d2=None,
                 little_m=None,
                 big_m=None,
                 spring_k1=None,
                 spring_k2=None,
                 b=None,
                 x=None,
                 x_dot=None,
                 theta=None,
                 theta_dot=None,
                 px_len=None,
                 scale=None,
                 pivot=False,
                 method='Euler',
                 dt=None,
                 font_size=None):
        """
        Main VisPy Canvas for simulation of physical system.

        Parameters
        ----------
        d1 : float
            Length of rod (in meters) from pivot to upper spring.
        d2 : float
            Length of rod (in meters) from pivot to lower spring.
        little_m : float
            Mass of attached cube (in kilograms).
        big_m : float
            Mass of rod (in kilograms).
        spring_k1 : float
            Spring constant of lower spring (in N/m).
        spring_k2 : float
            Spring constant of upper spring (in N/m).
        b : float
            Coefficient of quadratic sliding friction (in kg/m).
        x : float
            Initial x-position of mass (in m).
        x_dot : float
            Initial x-velocity of mass (in m/s).
        theta : float
            Initial angle of rod, with respect to vertical (in radians).
        theta_dot : float
            Initial angular velocity of rod (in rad/s).
        px_len : int
            Length of the rod, in pixels.
        scale : int
            Scaling factor to change size of elements.
        pivot : bool
            Switch for showing/hiding pivot point.
        method : str
            Method to use for updating.
        dt : float
            Time step for simulation.
        font_size : float
            Size of font for text elements, in points.

        Notes
        -----

        As of right now, the only supported methods are "euler" or
        "runge-kutta". These correspond to an Euler method or an
        order 3 Runge-Kutta method for updating x, theta, x dot, and theta dot.

        """

        app.Canvas.__init__(self, title='Wiggly Bar', size=(800, 800))

        # Some initialization constants that won't change
        self.standard_length = 0.97 + 0.55
        self.center = np.asarray((500, 450))
        self.visuals = []

        self._set_up_system(d1=d1,
                            d2=d2,
                            little_m=little_m,
                            big_m=big_m,
                            spring_k1=spring_k1,
                            spring_k2=spring_k2,
                            b=b,
                            x=x,
                            x_dot=x_dot,
                            theta=theta,
                            theta_dot=theta_dot,
                            px_len=px_len,
                            scale=scale,
                            pivot=pivot,
                            method=method,
                            dt=dt,
                            font_size=font_size)

        piv_x_y_px = np.asarray(
            (self.pivot_loc_px * np.sin(self.theta),
             -1 * self.pivot_loc_px * (np.cos(self.theta))))

        # Make the spring points
        points = make_spring(height=self.px_len / 4, radius=self.px_len / 24)

        # Put up a text visual to display time info
        self.font_size = 24. if font_size is None else font_size
        self.text = visuals.TextVisual('0:00.00',
                                       color='white',
                                       pos=[50, 250, 0],
                                       anchor_x='left',
                                       anchor_y='bottom')
        self.text.font_size = self.font_size

        # Let's put in more text so we know what method is being used to
        # update this
        self.method_text = visuals.TextVisual(
            'Method: {}'.format(self.method),
            color='white',
            pos=[50, 250 + 2 / 3 * font_size, 0],
            anchor_x='left',
            anchor_y='top')
        self.method_text.font_size = 2 / 3 * self.font_size

        # Get the pivoting bar ready
        self.rod = visuals.BoxVisual(width=self.px_len / 40,
                                     height=self.px_len / 40,
                                     depth=self.px_len,
                                     color='white')
        self.rod.transform = transforms.MatrixTransform()
        self.rod.transform.scale(
            (self.scale, self.scale * self.rod_scale, 0.0001))
        self.rod.transform.rotate(np.rad2deg(self.theta), (0, 0, 1))
        self.rod.transform.translate(self.center - piv_x_y_px)

        # Show the pivot point (optional)
        pivot_center = (self.center[0], self.center[1], -self.px_len / 75)
        self.center_point = visuals.SphereVisual(radius=self.px_len / 75,
                                                 color='red')
        self.center_point.transform = transforms.MatrixTransform()
        self.center_point.transform.scale((self.scale, self.scale, 0.0001))
        self.center_point.transform.translate(pivot_center)

        # Get the upper spring ready.
        self.spring_2 = visuals.TubeVisual(points,
                                           radius=self.px_len / 100,
                                           color=(0.5, 0.5, 1, 1))
        self.spring_2.transform = transforms.MatrixTransform()
        self.spring_2.transform.rotate(90, (0, 1, 0))
        self.spring_2.transform.scale((self.scale, self.scale, 0.0001))
        self.spring_2.transform.translate(self.center + self.s2_loc)

        # Get the lower spring ready.
        self.spring_1 = visuals.TubeVisual(points,
                                           radius=self.px_len / 100,
                                           color=(0.5, 0.5, 1, 1))
        self.spring_1.transform = transforms.MatrixTransform()
        self.spring_1.transform.rotate(90, (0, 1, 0))
        self.spring_1.transform.scale(
            (self.scale * (1.0 - (self.x * self.px_per_m) /
                           (self.scale * self.px_len / 2)), self.scale,
             0.0001))
        self.spring_1.transform.translate(self.center + self.s1_loc)

        # Finally, prepare the mass that is being moved
        self.mass = visuals.BoxVisual(width=self.px_len / 4,
                                      height=self.px_len / 8,
                                      depth=self.px_len / 4,
                                      color='white')
        self.mass.transform = transforms.MatrixTransform()
        self.mass.transform.scale((self.scale, self.scale, 0.0001))
        self.mass.transform.translate(self.center + self.mass_loc)

        # Append all the visuals
        self.visuals.append(self.center_point)
        self.visuals.append(self.rod)
        self.visuals.append(self.spring_2)
        self.visuals.append(self.spring_1)
        self.visuals.append(self.mass)
        self.visuals.append(self.text)
        self.visuals.append(self.method_text)

        # Set up a timer to update the image and give a real-time rendering
        self._timer = app.Timer('auto', connect=self.on_timer, start=True)
        self.show()
Esempio n. 30
0
    def __init__(self, list_of_charts, theta, omega, g, M, m, kp, kd, A, f, l,
                 scale, x, V, method, control, noise, save_charts, dt, tmax,
                 font_size):

        VisualModel.__init__(self)

        self.model = CranePhysicalModel(list_of_charts)
        self.list_of_charts = list_of_charts

        self._set_up_system(l=l,
                            g=g,
                            M=M,
                            m=m,
                            theta=theta,
                            omega=omega,
                            x=x,
                            V=V,
                            kp=kp,
                            kd=kd,
                            A=A,
                            f=f,
                            scale=scale,
                            method=method,
                            control=control,
                            noise=noise,
                            save_charts=save_charts,
                            dt=dt,
                            tmax=tmax,
                            font_size=font_size)

        # Put up a text visual to display time info
        self.font_size = 24. if font_size is None else font_size
        self.text = visuals.TextVisual('0:00.00',
                                       color='white',
                                       pos=[15, 50, 0],
                                       anchor_x='left',
                                       anchor_y='bottom')
        self.text.font_size = self.font_size

        self.hook_length = self.scale * 30.0
        self.hook_height = self.scale * 0.2

        self.hook = visuals.BoxVisual(width=1.0,
                                      height=1.0,
                                      depth=1.0,
                                      color='grey')
        self.hook.transform = transforms.MatrixTransform()
        self.hook.transform.scale((self.hook_length, self.hook_height, 0.001))
        self.hook.transform.translate(
            [self.hook_length / 2.016 + self.scale * self.model.x, 0.0])
        self.hook.transform.translate(self.center)

        self.rod_width = self.scale * self.model.l / 20.0
        self.rod = visuals.BoxVisual(width=1.0,
                                     height=1.0,
                                     depth=1.0,
                                     color='green')
        self.rod.transform = transforms.MatrixTransform()
        self.rod.transform.scale(
            (self.rod_width, self.scale * self.model.l, 0.0001))
        self.rod.transform.translate([0.0, self.scale * self.model.l / 2.0])
        self.rod.transform.rotate(np.rad2deg(self.model.theta), (0, 0, 1))
        self.rod.transform.translate([self.scale * self.model.x, 0.0])
        self.rod.transform.translate(self.center)

        # Append all the visuals
        self.visuals.append(self.rod)
        self.visuals.append(self.hook)
        self.visuals.append(self.text)