Exemplo n.º 1
0
    def put(self, sim_id):
        """
        Sets the simulation with the given name into a new state. Allowed values are:
        created, initialized, started, paused, stopped

        :param sim_id: The simulation id

        :< json string state: The state of the simulation to set

        :> json string state: The state of the simulation

        :status 404: {0}
        :status 401: {1}
        :status 400: The state transition is invalid
        :status 200: The state of the simulation with the given ID was successfully set
        """
        simulation = _get_simulation_or_abort(sim_id)

        if not UserAuthentication.can_modify(simulation):
            raise NRPServicesWrongUserException()

        body = request.get_json(force=True)
        try:
            simulation.state = body['state']
        except MachineError:
            raise NRPServicesStateException("Invalid transition (" +
                                            simulation.state + "->" +
                                            body['state'] + ")")
        return {'state': str(simulation.state)}, 200
Exemplo n.º 2
0
    def post(self, sim_id):
        """
        Extends the simulation timeout

        :param sim_id: The simulation id

        :status 404: {0}
        :status 402: Failed to extend the timeout
        :status 412: Failed due to simulation timeout type being 'simulation'
        :status 401: {1}
        :status 200: Success. The simulation timeout has been extended
        """
        simulation = _get_simulation_or_abort(sim_id)

        if not UserAuthentication.can_modify(simulation):
            raise NRPServicesWrongUserException()

        if simulation.timeout_type == TimeoutType.SIMULATION:
            return {}, 412

        new_timeout = simulation.kill_datetime + \
            datetime.timedelta(minutes=SIMULATION_TIMEOUT_EXTEND)

        if not simulation.cle.extend_simulation_timeout(new_timeout):
            return {}, 402

        simulation.kill_datetime = new_timeout

        return {}, 200
Exemplo n.º 3
0
    def get(self, sim_id):
        """
        Gets the simulation with the specified simulation id

        :param sim_id: The simulation id

        :> json string state: The current state of the simulation
        :> json integer simulationID: The id of the simulation (needed for further REST calls)
        :> json string environmentConfiguration: Path and name of the environment configuration file
        :> json string owner: The simulation owner (Unified Portal user id or 'hbp-default')
        :> json string creationDate: Date of creation of this simulation
        :> json string gzserverHost: Denotes where the simulation will run once started. Set to
                                     'local' for localhost and 'lugano' for a dedicate machine on
                                     the Lugano viz cluster
        :> json string reservation: the name of the cluster reservation subsequently used to
                                    allocate a job
        :> json string experimentID: The experiment ID if the experiment is using the storage
        :> json integer brainProcesses: Number of brain processes to use (overrides ExD conf.)
        :> json string creationUniqueID: unique creation ID (used by Frontend to identify this sim.)

        :status 404: {0}
        :status 401: {1}
        :status 200: The simulation with the given ID is successfully retrieved
        """
        simulation = _get_simulation_or_abort(sim_id)

        if not UserAuthentication.can_view(simulation):
            raise NRPServicesWrongUserException()

        return simulation, 200
Exemplo n.º 4
0
    def get(self, sim_id):
        """
        Gets all transfer functions (robot to neuron and neuron to robot) in a dictionary with
        string values.

        :param sim_id: The simulation ID

        :> json dict data: Dictionary containing all transfer functions ('name': 'source')
        :> json dict active: Dictionary containing a mask for active TFs ('name': 'isActive')

        :status 404: {0}
        :status 401: {1}
        :status 200: Transfer functions retrieved successfully
        """

        simulation = _get_simulation_or_abort(sim_id)

        if not UserAuthentication.can_view(simulation):
            raise NRPServicesWrongUserException()

        transfer_functions = dict()
        active_tfs_mask = dict()

        transfer_functions_list, active_tfs_mask_list = \
            simulation.cle.get_simulation_transfer_functions()

        for tf, tf_active in zip(transfer_functions_list,
                                 active_tfs_mask_list):
            name = get_tf_name(tf)
            transfer_functions[name] = tf
            active_tfs_mask[name] = tf_active

        return dict(data=transfer_functions, active=active_tfs_mask), 200
Exemplo n.º 5
0
    def post(self, sim_id):
        """
        Adds a new transfer function

        :param sim_id: The simulation ID

        :< string data: The source code of the transfer function

        :status 404: {0}
        :status 403: {1}
        :status 401: {2}
        :status 400: {3}
        :status 200: Success. The transfer function was successfully added
        """
        simulation = _get_simulation_or_abort(sim_id)
        if not UserAuthentication.can_modify(simulation):
            raise NRPServicesWrongUserException()

        transfer_function_source = request.data

        error_message = simulation.cle.add_simulation_transfer_function(
            transfer_function_source)
        if error_message:
            ex_msg = ("Adding a new Transfer Function failed: {error_msg}\n"
                      "Updated source:\n"
                      "{tf_src}").format(error_msg=error_message,
                                         tf_src=str(transfer_function_source))
            raise NRPServicesDuplicateNameException(ex_msg) if "duplicate" in error_message \
                else NRPServicesTransferFunctionException(ex_msg)

        return 200
Exemplo n.º 6
0
    def put(self, sim_id):
        """
        Set the populations of the brain in a simulation with the specified simulation id.

        :param sim_id: The simulation ID

        :< json dict brain_populations: A dictionary indexed by population names and containing
                                             neuron indices

        :< json string brain_type: Type of the brain file ('h5' or 'py')
        :< param brain_populations: Contents of the brain file. Encoding given in field data_type
        :< json string data_type: type of the data field ('text' or 'base64')
        :< json string change_population: indicates if it has to be changes
                                        in the transfer functions
        :> json string message: Error Message if there is a syntax error in the code
        :status 404: {0}
        :status 200: Success. The populations of the brain where successfully set
        """

        simulation = _get_simulation_or_abort(sim_id)
        if not UserAuthentication.can_modify(simulation):
            raise NRPServicesWrongUserException()

        body = request.get_json(force=True)

        result = simulation.cle.set_simulation_populations(
            brain_type=body['brain_type'],
            brain_populations=json.dumps(body['brain_populations']),
            data_type=body['data_type'],
            change_population=body['change_population'])

        if result.message:
            return {'error_message': result.message}, 400

        return {'message': 'Success'}, 200
Exemplo n.º 7
0
    def post(self, sim_id, command):
        """
        Issue user commands to the simulator recorder. See parameter description for
        supported query commands.

        :param sim_id: The simulation ID to command.
        :param command: The command to issue, supported: [start, stop, cancel, reset, save]

        :status 500: {0}
        :status 404: {1}
        :status 401: {2}
        :status 400: The command is invalid/refused by recorder - see message returned.
        :status 200: Success. The command was issued.
        """

        # validate simulation id
        sim = _get_simulation_or_abort(sim_id)

        # only the simulation owner can command the recorder
        if not UserAuthentication.can_modify(sim):
            raise NRPServicesWrongUserException()

        # pure local command to save file to storage
        if command == 'save':
            try:
                file_name = sim.lifecycle.save_record_to_user_storage()
                return {'filename': file_name}, 200

            except Exception as e:
                raise NRPServicesClientErrorException(
                    'Cannot copy record to client storage', error_code=404)

        else:

            # validate the remote command type
            valid_commands = {
                'start': SimulationRecorderRequest.START,
                'stop': SimulationRecorderRequest.STOP,
                'cancel': SimulationRecorderRequest.CANCEL,
                'reset': SimulationRecorderRequest.RESET
            }
            if command not in valid_commands:
                raise NRPServicesClientErrorException(
                    'Invalid recorder command: %s' % command, error_code=404)

            # command the recorder, if unsuccessful return the error message
            try:
                resp = sim.cle.command_simulation_recorder(
                    valid_commands[command])

                # check the command success, on failure return status 400 + error
                if not resp.value:
                    raise NRPServicesClientErrorException(resp.message)

                # successful, return status 200
                return 'success', 200

            # internal CLE ROS error if service call fails, notify frontend
            except ROSCLEClientException as e:
                raise NRPServicesGeneralException(str(e), 'CLE error', 500)
Exemplo n.º 8
0
    def put(self, sim_id, transfer_function_name, activate):
        """

        Sets the activation state of the transfer function

        :param sim_id: The simulation ID
        :param transfer_function_name: The name of the transfer function to be modified
        :param activate A boolean denoting the new desired activation status

        :status 404: {0}
        :status 401: {1}
        :status 400: {2}
        :status 200: Success. The activation state of the TF has been successfully changed

        """

        simulation = _get_simulation_or_abort(sim_id)
        if not UserAuthentication.can_modify(simulation):
            raise NRPServicesWrongUserException()

        activate_bool = activate.lower(
        ) == "true"  # convert unicode to boolean

        error_message = simulation.cle.activate_simulation_transfer_function(
            transfer_function_name, activate_bool)

        if error_message:
            raise NRPServicesTransferFunctionException(
                "Transfer function (de-)activation failed: {}\n".format(
                    error_message))

        return 200
Exemplo n.º 9
0
    def get(self, sim_id):
        """
        Gets the list of robots in the running simulation.
        """
        # pylint: disable=no-self-use
        sim = _get_simulation_or_abort(sim_id)

        if not UserAuthentication.can_view(sim):
            raise NRPServicesWrongUserException()

        try:
            robots = SimulationRobots.__get_simulation_robots(sim)
        except ROSCLEClientException as e:
            raise NRPServicesGeneralException(str(e), 'CLE error', 500)

        result = {
            'robots': [{
                ParamNames.ROBOT_ID:
                robot.robot_id,
                ParamNames.ROBOT_ABS_PATH:
                robot.robot_model,
                ParamNames.IS_CUSTOM:
                robot.is_custom,
                ParamNames.ROBOT_POSE:
                SimulationRobots.__jsonisePose(robot.pose)
            } for robot in robots]
        }
        return result, 200
Exemplo n.º 10
0
    def delete(self, sim_id, state_machine_name):
        """
        Delete a state machine

        :param sim_id: The simulation ID
        :param state_machine_name: The name of the state machine to be deleted

        :status 500: {0}
        :status 404: {1}
        :status 401: {2}
        :status 200: The delete operation was successfully called. This does not imply that the
                     state machine function was correctly deleted though.
        """
        simulation = _get_simulation_or_abort(sim_id)
        if not UserAuthentication.can_modify(simulation):
            raise NRPServicesWrongUserException()

        failure_message = "State machine destruction failed: "
        try:
            ok, response_message = simulation.delete_state_machine(
                state_machine_name)
            if ok:
                return "Success. The state machine was successfully deleted.", 200
        except Exception as e:
            info = exc_info()
            raise NRPServicesGeneralException(
                failure_message +
                " {0}: {1}".format(e.__class__.__name__, e.message),
                "State machine error",
            ), None, info[2]
        raise NRPServicesStateMachineException(
            failure_message + "\n" + response_message, 404)
Exemplo n.º 11
0
    def delete(self, sim_id, robot_id):
        """
        Delete a robot from the simulation.

        :param sim_id: The simulation ID.
        :param robot_id: The robot ID.

        :status 500: {0}
        :status 404: {1}
        :status 401: {2}
        :status 400: Invalid request, the JSON parameters are incorrect
        :status 200: The requested robot was deleted successfully
        """
        # pylint: disable=no-self-use
        sim = _get_simulation_or_abort(sim_id)

        if not UserAuthentication.can_modify(sim):
            raise NRPServicesWrongUserException()
        try:
            res, err = SimulationRobot.__delete_robot(sim, robot_id)

        except ROSCLEClientException as e:
            raise NRPServicesGeneralException(str(e), 'CLE error', 500)
        if not res:
            return {'res': err}, 404
        return {'res': 'success'}, 200
Exemplo n.º 12
0
    def get(self, sim_id):
        """
        Gets the simulation CSV recorders' content

        :param sim_id: The simulation ID whose transfer functions are retrieved will be saved

        :> json string file: CSV file name
        :> json array data: CSV data as a list of strings

        :status 500: Error when retrieving recorder files
        :status 404: {0}
        :status 401: {1}
        :status 200: Returns a list of recorded csv files and data
        """
        simulation = _get_simulation_or_abort(sim_id)
        if not UserAuthentication.matches_x_user_name_header(
                request, simulation.owner):
            raise NRPServicesWrongUserException()

        response = []
        csv_files = simulation.cle.get_simulation_CSV_recorders_files()
        if csv_files:
            for csv_file in csv_files:
                file_data = []
                response.append({"file": csv_file.name, "data": file_data})
                with open(csv_file.temporary_path) as csvfile:
                    spamreader = csv.reader(csvfile,
                                            delimiter=' ',
                                            quotechar='|')
                    for row in spamreader:
                        file_data.append(', '.join(row))

        return response, 200
Exemplo n.º 13
0
    def put(self, sim_id):
        """
        Change the material of a given visual. Currently, only the change of screen materials is
        implemented

        :param sim_id: The simulation ID

        :< json string visual_path: The path to the visual for which a change in material is
                                    requested
        :< json string material_name: The name of the material that will be applied

        :status 404: {0}
        :status 401: {1}
        :status 400: The parameters are invalid
        :status 200: Material applied successfully
        """
        simulation = _get_simulation_or_abort(sim_id)

        if not UserAuthentication.can_modify(simulation):
            raise NRPServicesWrongUserException()

        body = request.get_json(force=True)
        if 'visual_path' not in body:
            return "No visual_path given", 400
        if 'material' not in body:
            return "No material given", 400

        return self.__set_material(body['visual_path'], body['material'])
Exemplo n.º 14
0
    def put(self, sim_id, transfer_function_name):
        """
        Applies user changes to transfer function code

        :param sim_id: The simulation ID
        :param transfer_function_name: The name of the transfer function to be modified

        :< string data: The source code of the transfer function

        :status 404: {0}
        :status 403: {1}
        :status 401: {2}
        :status 400: {3}
        :status 200: Success. The transfer function was successfully patched
        """
        simulation = _get_simulation_or_abort(sim_id)
        if not UserAuthentication.can_modify(simulation):
            raise NRPServicesWrongUserException()

        transfer_function_source = request.data
        error_message = simulation.cle.edit_simulation_transfer_function(
            transfer_function_name, transfer_function_source)

        if error_message:
            ex_msg = ("Transfer Function patch failed: {error_msg}\n"
                      "Updated source:\n"
                      "{tf_src}").format(error_msg=error_message,
                                         tf_src=str(transfer_function_source))
            raise NRPServicesDuplicateNameException(ex_msg) if "duplicate" in error_message \
                else NRPServicesTransferFunctionException(ex_msg)

        return 200
Exemplo n.º 15
0
    def get(self, sim_id):
        """
        Get brain data of the simulation specified with simulation ID.

        :param sim_id: The simulation ID

        :> json string brain_type: Type of the brain file ('h5' or 'py')
        :> json string data_type: type of the data field ('text' or 'base64')
        :> json string data: Contents of the brain file. Encoding given in field data_type
        :> json dict brain_populations: A dictionary indexed by population names and containing
                                             neuron indices.

        :status 500: {0}
        :status 404: {1}
        :status 401: {2}
        :status 200: Success. The experiment brain file was retrieved
        """

        simulation = _get_simulation_or_abort(sim_id)

        if not UserAuthentication.can_view(simulation):
            raise NRPServicesWrongUserException()

        result = simulation.cle.get_simulation_brain()

        return {
            'data': result.brain_data,
            'brain_type': result.brain_type,
            'data_type': result.data_type,
            'brain_populations': json.loads(result.brain_populations)
        }, 200
Exemplo n.º 16
0
    def put(self, sim_id):
        """
        Set brain file of the simulation specified with simulation ID.
        Depending on the type of brain file, it has to be transmitted as text or as base64
        :param sim_id: The simulation ID

        :< json string brain_type: Type of the brain file ('h5' or 'py')
        :< json string data_type: type of the data field ('text' or 'base64')
        :< json string data: Contents of the brain file. Encoding given in field data_type
        :< json dict brain_populations: A dictionary indexed by population names and containing
                                        neuron indices
        :> json string error_message: Error Message if there is a syntax error in the code
        :> json int error_line: Line of code, where error occurred
        :> json int error_column: Column, where error occurred (if available)
        :> json bool handle_population_change: a flag indicating if user wants to change transfer
                                               functions according to population changes.

        :status 500: {0}
        :status 404: {1}
        :status 401: {2}
        :status 400: {3}
        :status 200: Success. The experiment brain file was replaced
        """

        simulation = _get_simulation_or_abort(sim_id)
        storage_client = StorageClient()
        if not UserAuthentication.can_modify(simulation):
            raise NRPServicesWrongUserException()

        body = request.get_json(force=True)

        file_url = body.get('urls', {}).get('fileUrl')
        if file_url:
            # TODO: fix server certificate and remove verify
            with requests.get(file_url, verify=False) as h5:
                filename = os.path.basename(file_url)
                with open(os.path.join(simulation.lifecycle.sim_dir, filename),
                          'w') as f:
                    f.write(h5.content)
                storage_client.create_or_update(simulation.token,
                                                simulation.experiment_id,
                                                filename, h5.content,
                                                "text/plain")

        result = simulation.cle.set_simulation_brain(
            brain_type=body['brain_type'],
            data=body['data'],
            data_type=body['data_type'],
            brain_populations=json.dumps(body['brain_populations']))

        if result.error_message:
            # Error in given brain
            return {
                'error_message': result.error_message,
                'error_line': result.error_line,
                'error_column': result.error_column
            }, 400
        # Success
        return {'message': "Success"}, 200
Exemplo n.º 17
0
    def put(self, sim_id, experiment_id):
        """
        Calls the CLE for resetting a given simulation to the last saved state in the storage.

        :param sim_id: The simulation ID.
        :param experiment_id: The experiment ID

        :> json resetType: the reset type the user wants to be performed, details about possible
                          values are given in
                          GazeboRosPackages/src/cle_ros_msgs/srv/ResetSimulation.srv

        :status 500: {0}
        :status 404: {1}
        :status 401: {2}
        :status 400: Invalid request, the JSON parameters are incorrect
        :status 200: The requested reset was performed successfully
        """
        sim = _get_simulation_or_abort(sim_id)

        if not UserAuthentication.can_modify(sim):
            raise NRPServicesWrongUserException()

        req_body = request.get_json(force=True)
        context_id = req_body.get('contextId', None)

        for missing_par in (par for par in self.ResetRequest.required if par not in req_body):
            raise NRPServicesClientErrorException('Missing parameter {}'.format(missing_par))

        for invalid_p in (par for par in req_body if par not in self.ResetRequest.resource_fields):
            raise NRPServicesClientErrorException('Invalid parameter {}'.format(invalid_p))

        reset_type = req_body.get('resetType')

        rsr = srv.ResetSimulationRequest

        try:
            if reset_type == rsr.RESET_ROBOT_POSE:
                sim.cle.reset(reset_type)
            elif reset_type == rsr.RESET_WORLD:
                sim.cle.reset(reset_type,
                              world_sdf=self._get_sdf_world_from_storage(experiment_id, context_id))
            elif reset_type == rsr.RESET_FULL:
                brain_path, populations, _ = \
                    self._get_brain_info_from_storage(experiment_id, context_id)

                if sim.playback_path is None:
                    self.reset_from_storage_all(sim, experiment_id, context_id)

                sim.cle.reset(reset_type,
                              world_sdf=self._get_sdf_world_from_storage(experiment_id, context_id),
                              brain_path=brain_path,
                              populations=populations)
            else:
                return {}, 400  # Other reset modes are unsupported

        except ROSCLEClientException as e:
            raise NRPServicesGeneralException(str(e), 'CLE error', 500)

        return {}, 200
Exemplo n.º 18
0
    def put(self, sim_id, state_machine_name):
        """
        Applies user changes to state machine code.
        If the simulation is paused or started, it will be paused.
        A stopped, created or failed simulation will fail the request with error code 403

        :param sim_id: The simulation ID
        :param state_machine_name: The name of the state machine to be modified

        :< json string data: The source code of the state machine

        :status 404: {0}
        :status 401: {1}
        :status 400: {2}
        :status 200: Success. The code was successfully patched
        """
        simulation = _get_simulation_or_abort(sim_id)
        assert simulation, Simulation
        if not UserAuthentication.can_modify(simulation):
            raise NRPServicesWrongUserException()

        state_machine_source = request.data
        try:
            simulation.set_state_machine_code(state_machine_name,
                                              state_machine_source)
            return "Success. The code was successfully patched.", 200
        except (AttributeError, NameError) as e:
            info = exc_info()
            raise NRPServicesStateMachineException(e.message,
                                                   400), None, info[2]

        except SyntaxError as e:
            info = exc_info()
            args_txt = ""
            for text in e.args:
                args_txt += " {0}".format(text)
            raise NRPServicesStateMachineException(
                "The source code is invalid: "
                "SyntaxError in line {0}{1}.".format(e.lineno, args_txt),
                400), None, info[2]

        except Exception as e:
            info = exc_info()
            raise NRPServicesGeneralException(
                "Update of state machine code failed. "
                "{0}: {1}".format(e.__class__.__name__, e.message),
                "State machine error"), None, info[2]
Exemplo n.º 19
0
    def get(self, sim_id):
        """
        Gets the state of the simulation with the specified simulation id. Possible values are:
        created, initialized, started, paused, stopped

        :param sim_id: The simulation id

        :> json string state: The state of the simulation

        :status 404: {0}
        :status 401: {1}
        :status 200: The state of the simulation with the given ID was successfully retrieved
        """
        simulation = _get_simulation_or_abort(sim_id)

        if not UserAuthentication.can_view(simulation):
            raise NRPServicesWrongUserException()

        return {'state': str(simulation.state)}, 200
Exemplo n.º 20
0
    def post(self, sim_id, robot_id):
        """
        Add a new robot to the simulation.

        :param sim_id: The simulation ID.
        :param robot_id: The robot string ID.

        :status 500: {0}
        :status 404: {1}
        :status 401: {2}
        :status 400: Invalid request, the JSON parameters are incorrect
        :status 200: The requested robot was created successfully
        """
        # pylint: disable=no-self-use
        sim = _get_simulation_or_abort(sim_id)

        if not UserAuthentication.can_modify(sim):
            raise NRPServicesWrongUserException()

        body = request.get_json(force=True)

        missing_parameters = [
            item for item in SimulationRobot.RobotPostRequest.required
            if item not in body
        ]
        if missing_parameters:
            raise NRPServicesClientErrorException('Missing parameter(s): ' +
                                                  ' '.join(missing_parameters))

        try:
            res, err = SimulationRobot.__add_new_robot(
                sim=sim,
                robot_id=robot_id,
                robot_model=body.get(ParamNames.ROBOT_MODEL),
                is_custom=(body.get(ParamNames.IS_CUSTOM, None) == 'True'),
                initial_pose=body.get(ParamNames.ROBOT_POSE, None))
        except ROSCLEClientException as e:
            raise NRPServicesGeneralException(str(e), 'CLE error', 500)

        if not res:
            return {'res': err}, 404
        return {'res': 'success'}, 200
Exemplo n.º 21
0
    def put(self, sim_id):
        """
        Save the simulation CSV recorders' content to the storage.

        :param sim_id: The simulation ID
        :status 500: Error when saving recorder files
        :status 404: {0}
        :status 401: {1}
        :status 200: Success. Files saved into storage
        """

        simulation = _get_simulation_or_abort(sim_id)
        if not UserAuthentication.matches_x_user_name_header(
                request, simulation.owner):
            raise NRPServicesWrongUserException()

        csv_files = simulation.cle.get_simulation_CSV_recorders_files()

        # Done here in order to avoid circular dependencies introduced by the
        # way we __init__ the rest_server module.
        from hbp_nrp_backend.storage_client_api.StorageClient \
            import StorageClient

        client = StorageClient()

        time_string = get_date_and_time_string()
        subfolder_name = string.join(['csv_records', time_string], '_')

        folder_uuid = client.create_folder(
            UserAuthentication.get_header_token(request),
            simulation.experiment_id, subfolder_name)['uuid']

        if csv_files:
            for csv_file in csv_files:
                with open(csv_file.temporary_path) as csvfile:
                    client.create_or_update(
                        UserAuthentication.get_header_token(request),
                        folder_uuid, csv_file.name, csvfile.read(),
                        'text/plain')
        return 200
Exemplo n.º 22
0
    def get(self, sim_id):
        """
        Gets the neurons of the brain in a simulation with the specified simulation id.

        :param sim_id: The simulation ID

        :> json array Populations: array of population dictionaries. Each dict contains population
                                   name, neuron indices, neuron model, parameters and gids

        :status 404: {0}
        :status 401: {1}
        :status 200: The neurons of the simulation with the given ID where successfully retrieved
        """
        simulation = _get_simulation_or_abort(sim_id)

        if not UserAuthentication.can_view(simulation):
            raise NRPServicesWrongUserException()

        # Get Neurons from cle
        neurons = simulation.cle.get_populations()

        return neurons, 200
Exemplo n.º 23
0
    def get(self, sim_id):
        """
        Returns the SDF file describing the world in which the simulation is carried out

        :> json string sdf: the SDF string describing the world excluding the robots involved

        :status 500: ROS service not available
        :status 401: {0}
        :status 400: A ROS error occurred
        :status 200: SDF file successfully returned
        """
        simulation = _get_simulation_or_abort(sim_id)

        if not UserAuthentication.can_view(simulation):
            raise NRPServicesWrongUserException()

        try:
            rospy.wait_for_service('/gazebo/export_world_sdf', 3)
        except rospy.ROSException as exc:
            raise NRPServicesUnavailableROSService(str(exc))

        dump_sdf_world = rospy.ServiceProxy('/gazebo/export_world_sdf',
                                            ExportWorldSDF)

        try:
            sdf_string = dump_sdf_world().sdf_dump
            tree = ET.fromstring(sdf_string)
            # remove all references to the robots in the sdf
            robots = simulation.cle.get_simulation_robots()
            for robot in robots:
                for m in tree.findall(".//model[@name='" + robot.robot_id +
                                      "']"):
                    m.getparent().remove(m)
            sdf_string = ET.tostring(tree, encoding='utf8', method='xml')
        except rospy.ServiceException as exc:
            raise NRPServicesClientErrorException(
                "Service did not process request:" + str(exc))

        return {"sdf": sdf_string}, 200
Exemplo n.º 24
0
    def get(self, sim_id, command):
        """
        Queries the simulation recorder for a value/status. See parameter description for
        supported query commands.

        :param sim_id: The simulation ID to command.
        :param command: The command to query, supported: [is-recording]

        :status 500: {0}
        :status 404: {1}
        :status 401: {2}
        :status 200: Success. The query was issued and value returned.
        """

        # validate simulation id, allow any users/viewers to query recorder
        sim = _get_simulation_or_abort(sim_id)

        if not UserAuthentication.can_view(sim):
            raise NRPServicesWrongUserException()

        # validate the command type
        if command not in ['is-recording', 'is-playingback']:
            raise NRPServicesClientErrorException(
                'Invalid recorder query: %s' % command, error_code=404)

        try:
            if command == 'is-recording':
                state = str(
                    sim.cle.command_simulation_recorder(
                        SimulationRecorderRequest.STATE).value)
            elif command == 'is-playingback':
                state = 'False' if sim.playback_path is None else 'True'

            return {'state': state}, 200

        # internal CLE ROS error if service call fails, notify frontend
        except ROSCLEClientException as e:
            raise NRPServicesGeneralException(str(e), 'CLE error', 500)
Exemplo n.º 25
0
    def get(self, sim_id, resource_type, resource_path):
        """
        Download the file in the resource_path for the give resource_type
        :param sim_id: The ID of the simulation whose files shall be handled
        :param resource_type: "robots", "brains", "environments", "files"
        :param resource_path: relative path the particular resource to be downloaded
        """
        # pylint: disable=no-self-use
        sim = _get_simulation_or_abort(sim_id)

        if not UserAuthentication.can_view(sim):
            raise NRPServicesWrongUserException()

        if resource_type not in SimulationFiles.RESOURCE_TYPES:
            raise NRPServicesGeneralException("Wrong resource_type specified",
                                              'Wrong Parameter', 500)
        try:
            ret, err = SimulationFiles.__download_file(sim, resource_type,
                                                       resource_path)
        except ROSCLEClientException as e:
            raise NRPServicesGeneralException(str(e), 'CLE error', 500)

        return ({'res': 'success'}, 200) if ret else ({'res': err}, 500)
Exemplo n.º 26
0
    def delete(self, sim_id, transfer_function_name):
        """
        Delete a transfer function

        :param sim_id: The simulation ID
        :param transfer_function_name: The name of the transfer function to be deleted

        :status 404: {0}
        :status 401: {1}
        :status 200: Success. The code was successfully patched
        """
        simulation = _get_simulation_or_abort(sim_id)
        if not UserAuthentication.can_modify(simulation):
            raise NRPServicesWrongUserException()

        response = simulation.cle.delete_simulation_transfer_function(
            transfer_function_name)

        if response is False:
            raise NRPServicesTransferFunctionException(
                "Transfer function delete failed: {}".format(
                    str(transfer_function_name)))
        return 200
Exemplo n.º 27
0
    def get(self, sim_id):
        """
        Get code of all state machines. This works in all simulation states except 'created', where
        it will deliver an empty dictionary.

        :param sim_id: The simulation ID

        :> json dict data: Dictionary containing all state machines ('name': 'source')

        :status 404: {0}
        :status 401: {1}
        :status 200: Success. The state machines were returned
        """
        simulation = _get_simulation_or_abort(sim_id)

        if not UserAuthentication.can_view(simulation):
            raise NRPServicesWrongUserException()

        state_machines = dict()
        for sm in simulation.state_machines:
            state_machines[sm.sm_id] = simulation.get_state_machine_code(
                sm.sm_id)

        return dict(data=state_machines), 200
Exemplo n.º 28
0
    def get(self, sim_id):
        """
        Gets simulation resource files of the experiment running for the simulation ID

        :param sim_id: The simulation ID

        :> json string resources: Resource files

        :status 500: {0}
        :status 404: {1}. Or, {2}.
        :status 401: {3}
        :status 200: Success. The simulation BIBI configuration files were retrieved
        """

        simulation = _get_simulation_or_abort(sim_id)

        if not UserAuthentication.can_view(simulation):
            raise NRPServicesWrongUserException()

        experiment_file = simulation.lifecycle.experiment_path

        if not os.path.isfile(experiment_file):
            raise NRPServicesClientErrorException(
                ErrorMessages.EXPERIMENT_CONF_FILE_NOT_FOUND_404,
                error_code=404)
        with open(experiment_file) as exd_file:
            experiment_dom = exp_conf_api_gen.CreateFromDocument(
                exd_file.read())

        bibi_fullpath = os.path.join(simulation.lifecycle.sim_dir,
                                     experiment_dom.bibiConf.src)

        if not os.path.isfile(bibi_fullpath):
            raise NRPServicesClientErrorException(
                ErrorMessages.EXPERIMENT_BIBI_FILE_NOT_FOUND_404,
                error_code=404)

        resources = []
        for conf in experiment_dom.configuration:
            resources.append({'file': conf.src, 'type': conf.type})

        with open(bibi_fullpath) as _file:
            bibi_dom = bibi_api_gen.CreateFromDocument(_file.read())

        for conf in bibi_dom.configuration:
            resources.append({'file': conf.src, 'type': conf.type})

        if simulation.private:
            root_dir = os.path.join(
                '/config-from-cloned-folder',
                os.path.basename(simulation.lifecycle.sim_dir))
        else:
            # Get the template experiment folder name, e.g., "template_husky"
            root_dir = os.path.join(
                '/config-from-template-folder',
                os.path.basename(os.path.dirname(experiment_file)))

        for conf in resources:
            conf['file'] = os.path.join(root_dir, conf['file'])
            conf['file_offset'] = len(root_dir) + 1

        return {'resources': resources}, 200