def _run_responsive_ui_thread(self) -> None: while True: if not self.running: with self._step_lock: if self._shutting_down or sim.simExtGetExitRequest(): break sim.simExtStep(False) time.sleep(0.01) # If the exit request was from the UI, then call shutdown, otherwise # shutdown caused this thread to terminate. if not self._shutting_down: self.shutdown()
def launch(self, scene_file="", headless=False, responsive_ui=False, blocking=False) -> None: """Launches CoppeliaSim. Launches the UI thread, waits until the UI thread has finished, this results in the current thread becoming the simulation thread. :param scene_file: The scene file to load. Empty string for empty scene. :param headless: Run CoppeliaSim in simulation mode. :param responsive_ui: If True, then a separate thread will be created to asynchronously step the UI of CoppeliaSim. Note, that will reduce the responsiveness of the simulation thread. :param blocking: Causes CoppeliaSim to launch as if running the default c++ client application. This is causes the function to block. For most users, this will be set to False. """ abs_scene_file = os.path.abspath(scene_file) if len(scene_file) > 0 and not os.path.isfile(abs_scene_file): raise PyRepError('Scene file does not exist: %s' % scene_file) cwd = os.getcwd() self._ui_thread = threading.Thread(target=self._run_ui_thread, args=(abs_scene_file, headless)) self._ui_thread.daemon = True self._ui_thread.start() while not sim.simExtCanInitSimThread(): time.sleep(0.1) sim.simExtSimThreadInit() time.sleep(0.2) # Stops CoppeliaSim crashing if restarted too quickly. if blocking: while not sim.simExtGetExitRequest(): sim.simExtStep() self.shutdown() elif responsive_ui: self._responsive_ui_thread = threading.Thread( target=self._run_responsive_ui_thread) self._responsive_ui_thread.daemon = True try: self._responsive_ui_thread.start() except (KeyboardInterrupt, SystemExit): if not self._shutting_down: self.shutdown() sys.exit() self.step() else: self.step() os.chdir(cwd) # Go back to the previous cwd
def set_joint_positions(self, positions: List[float], disable_dynamics: bool = False) -> None: """Sets the intrinsic position of the joints. See :py:meth:`Joint.set_joint_position` for more information. :param disable_dynamics: If True, then the position can be set even when the joint mode is in Force mode. It will disable dynamics, move the joint, and then re-enable dynamics. :param positions: A list of positions of the joints (angular or linear values depending on the joint type). """ self._assert_len(positions) if not disable_dynamics: [ sim.simSetJointPosition(jh, p) # type: ignore for jh, p in zip(self._joint_handles, positions) ] return is_model = self.is_model() if not is_model: self.set_model(True) prior = sim.simGetModelProperty(self.get_handle()) p = prior | sim.sim_modelproperty_not_dynamic # Disable the dynamics sim.simSetModelProperty(self._handle, p) with utils.step_lock: sim.simExtStep(True) # Have to step for changes to take effect [ sim.simSetJointPosition(jh, p) # type: ignore for jh, p in zip(self._joint_handles, positions) ] [ j.set_joint_target_position(p) # type: ignore for j, p in zip(self.joints, positions) ] with utils.step_lock: sim.simExtStep(True) # Have to step for changes to take effect # Re-enable the dynamics sim.simSetModelProperty(self._handle, prior) self.set_model(is_model)