def RotateComponents(self, theta, axis):
     '''Rotates all components in the module theta degrees about the provided axis.'''
     for _, comp in self.components.items():
         comp.RotateAxis(theta, axis)
     if self.refpoint:
         self.refpoint = MiroAPI.rotateVector(self.refpoint, theta, axis)
     if self.refcomp:
         self.refcomp_relpos = MiroAPI.rotateVector(self.refcomp_relpos,
                                                    theta, axis)
 def RotateModuleY(self, angle):
     '''Rotate a complete module about the Y axis in degrees'''
     ref = self.GetBaseComponent().GetPosition()
     for _, comp in self.components.items():
         comp.RotateAxis(angle, [0, 1, 0])
         dr = comp.GetPosition() - ref
         if np.linalg.norm(dr) > 0:
             dr_new = MiroAPI.rotateVector(dr, angle, [0, 1, 0])
             comp.MoveToPosition(ref + dr_new)
Beispiel #3
0
 def RotateAxis(self, theta, axis):
     '''Rotates the component an angle theta degrees around axis in global coordinates.'''
     MiroAPI.rotateBody(self.body, rotAngle=theta, rotAxis=axis)
     for name, linkp in self.linkpoints.items():
         linkp_new = MiroAPI.rotateVector(linkp,
                                          rotAngle=theta,
                                          rotAxis=axis)
         self.linkpoints.update({
             name:
             MiroAPI.rotateVector(linkp, rotAngle=theta, rotAxis=axis)
         })
     for name, linkd in self.linkdirs.items():
         linkd_new = MiroAPI.rotateVector(linkd,
                                          rotAngle=theta,
                                          rotAxis=axis)
         self.linkdirs.update({
             name:
             MiroAPI.rotateVector(linkd, rotAngle=theta, rotAxis=axis)
         })
    def ConnectComponents(self,
                          name_A,
                          point_A,
                          name_B,
                          point_B,
                          dist=0,
                          move=True,
                          show_warning=True,
                          link_name=False,
                          lock_link=False):
        comp_A = self.components[name_A]
        comp_B = self.components[name_B]

        if (move):
            self.GetComponent(name_B).MoveToMatch(point_B,
                                                  self.GetComponent(name_A),
                                                  point_A, dist)

        # Set Link position to the midpoint between the linkpoints
        linkpos = (comp_A.GetLinkPoint(point_A) +
                   comp_B.GetLinkPoint(point_B)) / 2

        # Get both link directions from the components
        linkdirA = comp_A.GetLinkDir(point_A)
        linkdirB = comp_B.GetLinkDir(point_B)

        # If the dot product is negative, then the angle between the links is > 180 degrees and the links are at least somewhat facing
        if np.linalg.norm(linkdirA) == 0:
            linkdir = linkdirB
        elif np.linalg.norm(linkdirB) == 0:
            linkdir = linkdirA
        elif np.dot(linkdirA, linkdirB) < 0:
            linkdir = linkdirA - linkdirB
            linkdir = linkdir / np.linalg.norm(linkdir)
        else:
            linkdir = linkdirA + linkdirB
            linkdir = linkdir / np.linalg.norm(linkdir)
            if show_warning:
                print(
                    'Warning: Non-facing links. The links between ' + name_A +
                    '.' + point_A + ' and ' + name_B + '.' + point_B +
                    ' are not facing eachother, check linkpoint and object orientation. Consider removing with MiroModule.RemoveHelpers() before running.'
                )

        hinge_link = MiroAPI.LinkBodies_Hinge(comp_A.GetBody(),
                                              comp_B.GetBody(), linkpos,
                                              linkdir)

        # Add the link to the module's dictionary of links
        if link_name:
            self.links.update({link_name: hinge_link})
        else:
            name = name_A + "." + point_A + "_TO_" + name_B + "." + point_B
            self.links.update({name: hinge_link})

        self.graph_links.append({
            'Source': name_A,
            'Target': name_B,
            'Weight': 1
        })

        if lock_link:
            rotVec = np.array([1, 1, 1])
            if np.dot(rotVec, linkdir) / (np.linalg.norm(rotVec) *
                                          np.linalg.norm(rotVec)) < 0.01:
                rotVec = np.array([1, -1, 1])
            rotVec = rotVec - np.dot(rotVec, linkdir) * linkdir
            rotVec = rotVec / np.linalg.norm(rotVec)
            # 90 degree rotated link to emulate 0-spin link
            hinge_link = MiroAPI.LinkBodies_Hinge(
                comp_A.GetBody(), comp_B.GetBody(), linkpos,
                MiroAPI.rotateVector(linkdir, 90, rotVec))
            if link_name:
                self.links.update({link_name + '_locker': hinge_link})
            else:
                name = name_A + "." + point_A + "_TO_" + name_B + "." + point_B + '_locker'
                self.links.update({name: hinge_link})
Beispiel #5
0
    def Set_Camera(self):
        '''This sets the camera during simulation. For internal usage when the simulation is being run, 
        use SetPerspective to configure the camera before running the simulation.'''
        if self.freecam:
            return
        if self.cycle:
            self.cam_to_obs = MiroAPI.rotateVector(self.cam_to_obs,
                                                   self.cycle_angle / self.fps,
                                                   [0, 1, 0],
                                                   rotDegrees=False)
            self.cam_to_obs = (49 * self.cam_to_obs +
                               self.followmod.GetCenterOfMassVelocity()) / 50
            self.cam_to_obs = self.cam_to_obs / np.linalg.norm(self.cam_to_obs)
            self.cam_pos = self.obs_pos - self.cam_to_obs
            MiroAPI.SetCamera(self.system_list, self.cam_pos, self.obs_pos)

        if self.follow_default:

            if np.linalg.norm(self.followmod.GetCenterOfMassVelocity()) > 1e-2:

                #oldest working
                #cam_to_obs[0] = cam_to_obs[0] * np.cos(self.follow_angle)
                #cam_to_obs[1] = cam_to_obs[0] * np.sin(self.follow_angle)
                #cam_to_obs[2] = cam_to_obs[2] * np.cos(self.follow_angle)
                self.obs_pos = (12 * self.obs_pos +
                                self.followmod.GetCenterOfMass()) / 13
                self.cam_up = (9 * self.cam_up + np.array([0, 1, 0])) / 10

                cam_to_obs = (
                    self.followmod.GetCenterOfMassVelocity() /
                    np.linalg.norm(self.followmod.GetCenterOfMassVelocity()))
                cam_to_obs *= self.follow_distance
                cam_pos = self.obs_pos - self.cam_to_obs
                cam_pos[1] += self.follow_height

                self.cam_pos = (9 * self.cam_pos +
                                cam_pos) / 10  # good val = 1/2
                MiroAPI.SetCamera(self.system_list, self.cam_pos, self.obs_pos,
                                  self.cam_up)

                cam_to_obs = (49 * self.cam_to_obs + cam_to_obs) / (49 + 1)

                self.cam_to_obs = cam_to_obs

        if self.camera_sweep:
            i = self.sweepstep
            sweep_divs = 100
            self.cam_pos = (
                (sweep_divs - i) * self.sweep_cam[self.sweepnr - 1] +
                (i) * self.sweep_cam[self.sweepnr]) / sweep_divs
            self.obs_pos = (
                (sweep_divs - i) * self.sweep_obs[self.sweepnr - 1] +
                (i) * self.sweep_obs[self.sweepnr]) / sweep_divs
            MiroAPI.SetCamera(self.system_list, self.cam_pos, self.obs_pos)
            self.sweepstep += 1
            if self.sweepstep > sweep_divs:
                self.sweepstep = 0
                self.sweepnr += 1
            if self.sweepnr >= self.sweepsteps:
                self.camera_sweep = False

        if not self.cycle and not self.follow:
            return