def get_image(self, grayscale=False): """Retrieve image.""" # Retrieve image from the vision sensor simulated in V-REP if self._handle < 0: if self._handle == MISSING_HANDLE: raise RuntimeError("Could not retrieve image from {}: missing " "name or handle.".format(self._name)) if self._handle == REMOVED_OBJ_HANDLE: raise RuntimeError("Could not retrieve image from {}: object " "removed.".format(self._name)) client_id = self.client_id if client_id is None: raise ConnectionError( "Could not retrieve image from {}: not connected to V-REP " "remote API server.".format(self._name)) res, resolution, image = vrep.simxGetVisionSensorImage( client_id, self._handle, grayscale, vrep.simx_opmode_blocking) if res != vrep.simx_return_ok: raise ServerError("Could not retrieve image from {}.".format( self._name)) # Convert misrepresented pixel values due to the underlying unsigned # type image = [val if val >= 0 else val + 256 for val in image] # If necessary, arrange RGB triplets width, height = resolution n_pixels = width * height if not grayscale: image = [image[p:p + 3] for p in range(0, 3 * n_pixels, 3)] # Arrange pixels in rows, reversing from bottom up to top down order return [ image[p:p + width] for p in reversed(range(0, n_pixels, width)) ]
def get_near_clip_plane(self, prec=None): """Retrieve near clipping plane.""" if self._handle < 0: if self._handle == MISSING_HANDLE: raise RuntimeError( "Could not retrieve near clipping plane of {}: missing " "name or handle.".format(self._name)) if self._handle == REMOVED_OBJ_HANDLE: raise RuntimeError( "Could not retrieve near clipping plane of {}: object " "removed.".format(self._name)) client_id = self.client_id if client_id is None: raise ConnectionError( "Could not retrieve near clipping plane of {}: not connected " "to V-REP remote API server.".format(self._name)) res, clip_plane = vrep.simxGetObjectFloatParameter( client_id, self._handle, vrep.sim_visionfloatparam_near_clipping, vrep.simx_opmode_blocking) if res != vrep.simx_return_ok: raise ServerError("Could not retrieve near clipping plane of {}." "".format(self._name)) if prec is not None: clip_plane = round(clip_plane, prec) # near clipping plane may be # slightly imprecise due to # the use of single-precision # floating-point format by # V-REP return clip_plane
def get_distance(self, fast=True, prec=None): """Retrieve distance to the detected point.""" if self._handle < 0: if self._handle == MISSING_HANDLE: raise RuntimeError("Could not retrieve data from {}: missing " "name or handle.".format(self._name)) if self._handle == REMOVED_OBJ_HANDLE: raise RuntimeError("Could not retrieve data from {}: object " "removed.".format(self._name)) client_id = self.client_id if client_id is None: raise ConnectionError( "Could not retrieve data from {}: not connected to V-REP " "remote API server.".format(self._name)) res, detect, point, _, _ = vrep.simxReadProximitySensor( client_id, self._handle, vrep.simx_opmode_blocking) if res == vrep.simx_return_ok: if detect: if fast: distance = point[2] else: distance = math.sqrt(sum(coord * coord for coord in point)) return distance if prec is None else round(distance, prec) else: return None elif res == vrep.simx_return_novalue_flag: return None else: raise ServerError("Could not retrieve data from {}.".format( self._name))
def get_depth_buffer(self, prec=None): """Retrieve depth buffer.""" # Retrieve depth buffer from the vision sensor simulated in V-REP if self._handle < 0: if self._handle == MISSING_HANDLE: raise RuntimeError( "Could not retrieve depth buffer from {}: missing name or " "handle.".format(self._name)) if self._handle == REMOVED_OBJ_HANDLE: raise RuntimeError("Could not retrieve depth buffer from {}: " "object removed.".format(self._name)) client_id = self.client_id if client_id is None: raise ConnectionError( "Could not retrieve depth buffer from {}: not connected to " "V-REP remote API server.".format(self._name)) res, resolution, buffer = vrep.simxGetVisionSensorDepthBuffer( client_id, self._handle, vrep.simx_opmode_blocking) if res != vrep.simx_return_ok: raise ServerError( "Could not retrieve depth buffer from {}.".format(self._name)) # If necessary, round depth values if prec is not None: buffer = [round(val, prec) for val in buffer] # Arrange pixels in rows, reversing from bottom up to top down order width, height = resolution return [ buffer[p:p + width] for p in reversed(range(0, width * height, width)) ]
def set_position(self, position, relative=None, allow_in_sim=False): """Set object position.""" if self._handle < 0: if self._handle == MISSING_HANDLE: raise RuntimeError("Could not set position of {}: missing " "name or handle.".format(self._name)) if self._handle == REMOVED_OBJ_HANDLE: raise RuntimeError("Could not set position of {}: object " "removed.".format(self._name)) client_id = self.client_id if client_id is None: raise ConnectionError( "Could not set position of {}: not connected to V-REP remote " "API server.".format(self._name)) if not allow_in_sim and self.vrep_sim.is_sim_started(): raise SimulationError( "Could not set position of {}: setting position not allowed " "during simulation.".format(self._name)) relative_handle = to_handle(relative, "relative") res = vrep.simxSetObjectPosition(client_id, self._handle, relative_handle, position, vrep.simx_opmode_blocking) if res != vrep.simx_return_ok: raise ServerError("Could not set position of {}.".format( self._name))
def set_parent(self, parent, keep_pos=True): """Set object parent.""" if self._handle < 0: if self._handle == MISSING_HANDLE: raise RuntimeError("Could not set parent of {}: missing name " "or handle.".format(self._name)) if self._handle == REMOVED_OBJ_HANDLE: raise RuntimeError("Could not set parent of {}: object " "removed.".format(self._name)) client_id = self.client_id if client_id is None: raise ConnectionError( "Could not set parent of {}: not connected to V-REP remote " "API server.".format(self._name)) parent_handle = to_handle(parent, "parent") res = vrep.simxSetObjectParent(client_id, self._handle, parent_handle, keep_pos, vrep.simx_opmode_blocking) if res != vrep.simx_return_ok: raise ServerError("Could not set parent of {}.".format(self._name)) if self._parent is not None: self._parent.unregister_child(self) self._parent = None if isinstance(parent, SceneObject): parent.register_child(self) self._parent = parent
def get_position(self, relative=None, prec=None): """Retrieve object position.""" if self._handle < 0: if self._handle == MISSING_HANDLE: raise RuntimeError( "Could not retrieve position of {}: missing name or " "handle.".format(self._name)) if self._handle == REMOVED_OBJ_HANDLE: raise RuntimeError("Could not retrieve position of {}: object " "removed.".format(self._name)) client_id = self.client_id if client_id is None: raise ConnectionError( "Could not retrieve position of {}: not connected to V-REP " "remote API server.".format(self._name)) relative_handle = to_handle(relative, "relative") res, position = vrep.simxGetObjectPosition(client_id, self._handle, relative_handle, vrep.simx_opmode_blocking) if res != vrep.simx_return_ok: raise ServerError("Could not retrieve position of {}.".format( self._name)) if prec is None: return position else: return [round(coord, prec) for coord in position]
def set_orientation(self, orientation, relative=None, allow_in_sim=False): """Set object orientation specified as Euler angles about x, y, and z axes of the reference frame, each angle between -pi and pi. """ if self._handle < 0: if self._handle == MISSING_HANDLE: raise RuntimeError("Could not set orientation of {}: missing " "name or handle.".format(self._name)) if self._handle == REMOVED_OBJ_HANDLE: raise RuntimeError("Could not set orientation of {}: object " "removed.".format(self._name)) client_id = self.client_id if client_id is None: raise ConnectionError( "Could not set orientation of {}: not connected to V-REP " "remote API server.".format(self._name)) if not allow_in_sim and self.vrep_sim.is_sim_started(): raise SimulationError( "Could not set orientation of {}: setting orientation not " "allowed during simulation.".format(self._name)) relative_handle = to_handle(relative, "relative") res = vrep.simxSetObjectOrientation(client_id, self._handle, relative_handle, orientation, vrep.simx_opmode_blocking) if res != vrep.simx_return_ok: raise ServerError("Could not set orientation of {}.".format( self._name))
def get_orientation(self, relative=None, prec=None): """Retrieve object orientation specified as Euler angles about x, y, and z axes of the reference frame, each angle between -pi and pi. """ if self._handle < 0: if self._handle == MISSING_HANDLE: raise RuntimeError( "Could not retrieve orientation of {}: missing name or " "handle.".format(self._name)) if self._handle == REMOVED_OBJ_HANDLE: raise RuntimeError("Could not retrieve orientation of {}: " "object removed.".format(self._name)) client_id = self.client_id if client_id is None: raise ConnectionError( "Could not retrieve orientation of {}: not connected to V-REP " "remote API server.".format(self._name)) relative_handle = to_handle(relative, "relative") res, orientation = vrep.simxGetObjectOrientation( client_id, self._handle, relative_handle, vrep.simx_opmode_blocking) if res != vrep.simx_return_ok: raise ServerError("Could not retrieve orientation of {}.".format( self._name)) if prec is None: return orientation else: return [round(angle, prec) for angle in orientation]
def set_resolution(self, resolution): """Set resolution.""" if self._handle < 0: if self._handle == MISSING_HANDLE: raise RuntimeError("Could not set resolution of {}: missing " "name or handle.".format(self._name)) if self._handle == REMOVED_OBJ_HANDLE: raise RuntimeError("Could not set resolution of {}: object " "removed.".format(self._name)) client_id = self.client_id if client_id is None: raise ConnectionError( "Could not set resolution of {}: not connected to V-REP " "remote API server.".format(self._name)) res = vrep.simxSetObjectIntParameter( client_id, self._handle, vrep.sim_visionintparam_resolution_x, resolution[0], vrep.simx_opmode_blocking) if res != vrep.simx_return_ok: raise ServerError("Could not set resolution of {}." "".format(self._name)) res = vrep.simxSetObjectIntParameter( client_id, self._handle, vrep.sim_visionintparam_resolution_y, resolution[1], vrep.simx_opmode_blocking) if res != vrep.simx_return_ok: raise ServerError("Could not set resolution of {}." "".format(self._name))
def trig_sim_step(self): """Trigger V-REP simulation step.""" if self._client_id is None: raise ConnectionError("Could not trigger V-REP simulation step: " "not connected to V-REP remote API server.") res = vrep.simxSynchronousTrigger(self._client_id) if res != vrep.simx_return_ok: raise ServerError("Could not trigger V-REP simulation step.")
def get_scene_path(self): """Retrieve scene path.""" if self._client_id is None: raise ConnectionError("Could not retrieve scene path: not " "connected to V-REP remote API server.") res, scene_path = vrep.simxGetStringParameter( self._client_id, vrep.sim_stringparam_scene_path_and_name, vrep.simx_opmode_blocking) if res != vrep.simx_return_ok: raise ServerError("Could not retrieve scene path.") return scene_path
def get_dyn_eng_name(self): """Retrieve dynamics engine name.""" dyn_engs_names = {0: "Bullet", 1: "ODE", 2: "Vortex", 3: "Newton"} if self._client_id is None: raise ConnectionError("Could not retrieve dynamics engine name: " "not connected to V-REP remote API server.") res, dyn_eng_id = vrep.simxGetIntegerParameter( self._client_id, vrep.sim_intparam_dynamic_engine, vrep.simx_opmode_blocking) if res != vrep.simx_return_ok: raise ServerError("Could not retrieve dynamics engine name.") return dyn_engs_names[dyn_eng_id]
def connect(self, verbose=None): """Connect to V-REP remote API server.""" global _vrep_sim # If necessary, determine whether messages should be displayed if verbose is None: verbose = self.verbose # Check if connection to V-REP is already established if _vrep_sim is None: conn_msg = "connected" else: if self._client_id is not None: conn_msg = "reconnected" else: raise ConnectionError( "Could not connect to V-REP remote API server at {0}:{1}: " "another connection to V-REP remote API server already " "established.".format(self._addr, self._port)) # Just in case, close all opened connections to V-REP vrep.simxFinish(-1) self._client_id = None _vrep_sim = None # Connect to V-REP client_id = vrep.simxStart(self._addr, self._port, self._wait, not self._reconnect, self._timeout, self._cycle) if client_id == -1: raise ConnectionError( "Failed to connect to V-REP remote API server at " "{0}:{1}.".format(self._addr, self._port)) self._client_id = client_id _vrep_sim = self # If necessary, display confirmation message if verbose: print("Successfully {0} to V-REP remote API server at " "{1}:{2}.".format(conn_msg, self._addr, self._port))
def get_names(self): """Retrieve names of component scene objects.""" client_id = self.client_id if client_id is None: raise ConnectionError( "Could not retrieve names of {}: not connected to V-REP " "remote API server.".format(self._name)) res, _, _, _, names = vrep.simxGetObjectGroupData( client_id, self._handle, 0, vrep.simx_opmode_blocking) if res != vrep.simx_return_ok: raise ServerError("Could not retrieve names of {}.".format( self._name)) return names
def get_version(self): """Retrieve V-REP version.""" if self._client_id is None: raise ConnectionError("Could not retrieve V-REP version: not " "connected to V-REP remote API server.") res, version = vrep.simxGetIntegerParameter( self._client_id, vrep.sim_intparam_program_version, vrep.simx_opmode_blocking) if res != vrep.simx_return_ok: raise ServerError("Could not retrieve V-REP version.") return "{x}.{y}.{z}".format(x=version // 10000, y=(version // 100) % 100, z=version % 100)
def load_scene(self, filename, server_side=True): """Load scene from file.""" SERVER_SIDE = 0x00 CLIENT_SIDE = 0x01 if self._client_id is None: raise ConnectionError( "Could not load scene from file {}: not connected to V-REP " "remote API server.".format(filename)) side = SERVER_SIDE if server_side else CLIENT_SIDE res = vrep.simxLoadScene(self._client_id, filename, side, vrep.simx_opmode_blocking) if res != vrep.simx_return_ok: raise ServerError("Could not load scene from file {}." "".format(filename))
def get_positions(self, prec=None): """Retrieve positions of component scene objects.""" client_id = self.client_id if client_id is None: raise ConnectionError( "Could not retrieve positions of {}: not connected to V-REP " "remote API server.".format(self._name)) res, _, _, positions, _ = vrep.simxGetObjectGroupData( client_id, self._handle, 3, vrep.simx_opmode_blocking) if res != vrep.simx_return_ok: raise ServerError("Could not retrieve positions of {}.".format( self._name)) if prec is not None: positions = [round(coord, prec) for coord in positions] return [positions[p:p + 3] for p in range(0, len(positions), 3)]
def _get_handle(self): """Retrieve collection handle.""" if not self._name: raise RuntimeError("Could not retrieve handle to {}: missing name." "".format(EMPTY_NAME)) client_id = self.client_id if client_id is None: raise ConnectionError( "Could not retrieve handle to {}: not connected to V-REP " "remote API server.".format(self._name)) res, handle = vrep.simxGetCollectionHandle(client_id, self._name, vrep.simx_opmode_blocking) if res != vrep.simx_return_ok: raise ServerError("Could not retrieve handle to {}.".format( self._name)) return handle
def get_sim_dt(self, prec=None): """Retrieve V-REP simulation time step.""" if self._client_id is None: raise ConnectionError( "Could not retrieve V-REP simulation time step: not connected " "to V-REP remote API server.") res, sim_dt = vrep.simxGetFloatingParameter( self._client_id, vrep.sim_floatparam_simulation_time_step, vrep.simx_opmode_blocking) if res != vrep.simx_return_ok: raise ServerError("Could not retrieve V-REP simulation time step.") if prec is not None: sim_dt = round(sim_dt, prec) # V-REP simulation time step may be # slightly imprecise due to the use # of single-precision floating-point # format in V-REP return sim_dt
def get_orientations(self, prec=None): """Retrieve orientations of component scene objects, specified as Euler angles about x, y, and z axes of the absolute reference frame, each angle between -pi and pi. """ client_id = self.client_id if client_id is None: raise ConnectionError( "Could not retrieve orientations of {}: not connected to " "V-REP remote API server.".format(self._name)) res, _, _, orientations, _ = vrep.simxGetObjectGroupData( client_id, self._handle, 5, vrep.simx_opmode_blocking) if res != vrep.simx_return_ok: raise ServerError("Could not retrieve orientations of {}.".format( self._name)) if prec is not None: orientations = [round(angle, prec) for angle in orientations] return [orientations[o:o + 3] for o in range(0, len(orientations), 3)]
def call_script_func(self, funcname, script_type='customization', args_int=[], args_float=[], args_string=[], args_buf=bytearray()): """Call function from associated script.""" ASSOC_SCRIPT_TYPES = { 'child': vrep.sim_scripttype_childscript, 'customization': vrep.sim_scripttype_customizationscript } # Validate script type try: vrep_script_type = ASSOC_SCRIPT_TYPES[script_type] except KeyError: raise ValueError("Script type is not supported.") # Call function from the script if self._handle == REMOVED_OBJ_HANDLE: raise RuntimeError("Could not call function {0} from {1} script " "associated with {2}: object removed." "".format(funcname, script_type, self._name)) if self._name == EMPTY_NAME: raise RuntimeError( "Could not call function {0} from {1} script associated with " "{2}: missing name.".format(funcname, script_type, self._name)) client_id = self.client_id if client_id is None: raise ConnectionError( "Could not call function {0} from {1} script associated with " "{2}: not connected to V-REP remote API server." "".format(funcname, script_type, self._name)) res, rets_int, rets_float, rets_string, rets_buf = \ vrep.simxCallScriptFunction( client_id, self._name, vrep_script_type, funcname, args_int, args_float, args_string, args_buf, vrep.simx_opmode_blocking) if res != vrep.simx_return_ok: raise ServerError( "Could not call function {0} from {1} script associated with " "{2}.".format(funcname, script_type, self._name)) return rets_int, rets_float, rets_string, rets_buf
def stop_sim(self, verbose=None): """Stop V-REP simulation.""" # If necessary, determine whether messages should be displayed if verbose is None: verbose = self.verbose # Stop V-REP simulation if self._client_id is None: raise ConnectionError("Could not stop V-REP simulation: not " "connected to V-REP remote API server.") res = vrep.simxStopSimulation(self._client_id, vrep.simx_opmode_blocking) if res not in (vrep.simx_return_ok, vrep.simx_return_novalue_flag): raise ServerError("Could not stop V-REP simulation.") # If necessary, display confirmation message if verbose: print("V-REP simulation stopped at " "{}.".format(time.strftime("%H:%M:%S")))
def set_velocity(self, velocity): """Set motor velocity.""" if self._handle < 0: if self._handle == MISSING_HANDLE: raise RuntimeError("Could not set {} velocity: missing name " "or handle.".format(self._name)) if self._handle == REMOVED_OBJ_HANDLE: raise RuntimeError("Could not set {} velocity: object removed." "".format(self._name)) client_id = self.client_id if client_id is None: raise ConnectionError( "Could not set {} velocity: not connected to V-REP remote API " "server.".format(self._name)) res = vrep.simxSetJointTargetVelocity(client_id, self._handle, velocity, vrep.simx_opmode_blocking) if res != vrep.simx_return_ok: raise ServerError("Could not set {} velocity.".format(self._name))
def remove(self): """Remove model from scene.""" if self._handle < 0: if self._handle == MISSING_HANDLE: raise RuntimeError("Could not remove {}: missing name or " "handle.".format(self._name)) if self._handle == REMOVED_OBJ_HANDLE: raise RuntimeError("Could not remove {}: object already " "removed.".format(self._name)) client_id = self.client_id if client_id is None: raise ConnectionError( "Could not remove {}: not connected to V-REP remote API " "server.".format(self._name)) res = vrep.simxRemoveModel(client_id, self._handle, vrep.simx_opmode_blocking) if res != vrep.simx_return_ok: raise ServerError("Could not remove {}.".format(self._name)) self.set_removed()
def copy_paste(self): """Copy and paste object.""" if self._handle < 0: if self._handle == MISSING_HANDLE: raise RuntimeError("Could not copy and paste {}: missing name " "or handle.".format(self._name)) if self._handle == REMOVED_OBJ_HANDLE: raise RuntimeError("Could not copy and paste {}: object " "removed.".format(self._name)) client_id = self.client_id if client_id is None: raise ConnectionError( "Could not copy and paste {}: not connected to V-REP remote " "API server.".format(self._name)) res, handles = vrep.simxCopyPasteObjects(client_id, [self._handle], vrep.simx_opmode_blocking) if res != vrep.simx_return_ok: raise ServerError("Could not copy and paste {}.".format( self._name)) return handles[0]
def get_parent_handle(self): """Retrieve handle to object parent.""" if self._handle < 0: if self._handle == MISSING_HANDLE: raise RuntimeError( "Could not retrieve handle to the parent of {}: missing " "name or handle.".format(self._name)) if self._handle == REMOVED_OBJ_HANDLE: raise RuntimeError("Could not retrieve handle to the parent " "of {}: object removed.".format(self._name)) client_id = self.client_id if client_id is None: raise ConnectionError( "Could not retrieve handle to the parent of {}: not connected " "to V-REP remote API server.".format(self._name)) res, handle = vrep.simxGetObjectParent(client_id, self._handle, vrep.simx_opmode_blocking) if res != vrep.simx_return_ok: raise ServerError("Could not retrieve handle to the parent of " "{}.".format(self._name)) return handle if handle >= 0 else None
def set_near_clip_plane(self, clip_plane): """Set near clipping plane.""" if self._handle < 0: if self._handle == MISSING_HANDLE: raise RuntimeError( "Could not set near clipping plane of {}: missing name or " "handle.".format(self._name)) if self._handle == REMOVED_OBJ_HANDLE: raise RuntimeError("Could not set near clipping plane of {}: " "object removed.".format(self._name)) client_id = self.client_id if client_id is None: raise ConnectionError( "Could not set near clipping plane of {}: not connected to " "V-REP remote API server.".format(self._name)) res = vrep.simxSetObjectFloatParameter( client_id, self._handle, vrep.sim_visionfloatparam_near_clipping, clip_plane, vrep.simx_opmode_blocking) if res != vrep.simx_return_ok: raise ServerError("Could not set near clipping plane of {}." "".format(self._name))
def is_sim_started(self): """Retrieve whether V-REP simulation is started. The return value may be inaccurate if the function is called immediately after starting or stopping a simulation; in such a case, introducing a short delay before calling it should help. """ SIM_NOT_STOPPED = 0x01 # Retrieve whether V-REP is currently waiting for a trigger signal; # the result by itself, however, is not conclusive as to whether a # simulation is started or not (not waiting for a trigger signal does # not necessarily mean that a simulation is not started because there # may be unprocessed trigger signals during a simulation, in # which case V-REP will be advancing the simulation without reporting # that it needs to wait for a trigger signal); this operation is # performed only to receive a new message from the V-REP remote API # server so that the next operation could operate on up-to-date data if self._client_id is None: raise ConnectionError( "Could not retrieve whether V-REP simulation is started: not " "connected to V-REP remote API server.") res, _ = vrep.simxGetBooleanParameter( self._client_id, vrep.sim_boolparam_waiting_for_trigger, vrep.simx_opmode_blocking) if res != vrep.simx_return_ok: raise ServerError("Could not retrieve whether V-REP simulation is " "started.") # Retrieve the server state from the last message received from the # V-REP remote API server res, server_state = vrep.simxGetInMessageInfo( self._client_id, vrep.simx_headeroffset_server_state) if res == -1: raise ServerError("Could not retrieve whether V-REP simulation is " "started.") # Determine whether V-REP simulation is started return bool(server_state & SIM_NOT_STOPPED)
def get_dyn_eng_dt(self, prec=None): """Retrieve dynamics engine time step.""" vrep.sim_floatparam_dynamic_step_size = 3 # constant missing in Python # binding to V-REP remote # API if self._client_id is None: raise ConnectionError( "Could not retrieve dynamics engine time step: not connected " "to V-REP remote API server.") res, dyn_eng_dt = vrep.simxGetFloatingParameter( self._client_id, vrep.sim_floatparam_dynamic_step_size, vrep.simx_opmode_blocking) if res != vrep.simx_return_ok: raise ServerError("Could not retrieve dynamics engine time step.") if prec is not None: dyn_eng_dt = round(dyn_eng_dt, prec) # dynamics engine time step # may be slightly imprecise # due to the use of # single-precision # floating-point format in # V-REP return dyn_eng_dt