示例#1
0
 def get_trace(
     self,
     sid: SimulationID,
     vid: Optional[VehicleID] = None
 ) -> List[Tuple[str, str, int, DataResponse]]:
     """
     Return all the collected data of a single or all participants in a simulation.
     :param sid: The simulation to request all the collected data from.
     :param vid: The vehicle whose collected data has to be returned. If None this method returns all the collected
     data.
     :return: The JSON serialized object representing all the collected data of a simulation or a participant in a
     simulation.
     """
     from drivebuildclient.httpUtil import do_get_request
     import dill as pickle
     args = {"sid": sid.SerializeToString()}
     if vid:
         args["vid"] = vid.SerializeToString()
     response = do_get_request(self.host, self.port, "/stats/trace", args)
     if response.status == 200:
         response_content = b"".join(response.readlines())
         trace_data = pickle.loads(response_content)
         trace = []
         for entry in trace_data:
             sid = SimulationID()
             sid.sid = str(entry[0])
             vid = VehicleID()
             vid.vid = entry[1]
             data = DataResponse()
             data.ParseFromString(entry[3])
             trace.append((sid, vid, entry[2], data))
         return trace
     else:
         AIExchangeService._print_error(response)
         return "The trace could not be retrieved."
示例#2
0
def extract_sid() -> Tuple[Optional[bytes], Optional[SimulationID]]:
    from flask import request
    serialized_sid_b = request.args.get("sid", default=None)
    if serialized_sid_b:
        serialized_sid = serialized_sid_b.encode()
        sid = SimulationID()
        sid.ParseFromString(serialized_sid)
        return serialized_sid, sid
    else:
        return None, None
示例#3
0
 def _generate_sid() -> SimulationID:
     sid_cursor = _DB_CONNECTION.run_query("""
     INSERT INTO tests VALUES (DEFAULT, NULL, NULL, NULL, NULL, NULL, NULL, NULL) RETURNING sid;
     """)
     if sid_cursor:
         result = sid_cursor.fetchall()
         sid = SimulationID()
         sid.sid = str(result[0][0])
         return sid
     else:
         _logger.error("Generation of sid failed.")
示例#4
0
 def control(self, sid: SimulationID, vid: VehicleID,
             commands: Control) -> Optional[Void]:
     """
     Control the simulation or a certain vehicle in the simulation.
     :param sid: The ID the simulation either to control or containing th vehicle to control.
     :param vid: The ID of the vehicle to possibly control.
     :param commands: The command either controlling a simulation or a vehicle in a simualtion. To define a command
     controlling a simulation you can use commands like:
     control = Control()
     control.simCommand.command = Control.SimCommand.Command.SUCCEED  # Force simulation to succeed
     control.simCommand.command = Control.SimCommand.Command.FAIL  # Force simulation to fail
     control.simCommand.command = Control.SimCommand.Command.CANCEL  # Force simulation to be cancelled/skipped
     For controlling a vehicle you have to define steering, acceleration and brake values:
     control = Control()
     control.avCommand.accelerate = <Acceleration intensity having a value between 0.0 and 1.0>
     control.avCommand.steer = <A steering value between -1.0 and 1.0 (Negative value steers left; a positive one
     steers right)>
     control.avCommand.brake = <Brake intensity having a value between 0.0 and 1.0>
     :return: A Void object possibly containing a info message.
     """
     from drivebuildclient.httpUtil import do_mixed_request
     response = do_mixed_request(self.host, self.port, "/ai/control", {
         "sid": sid.SerializeToString(),
         "vid": vid.SerializeToString()
     }, commands.SerializeToString())
     if response.status == 200:
         void = Void()
         void.ParseFromString(b"".join(response.readlines()))
         return void
     else:
         AIExchangeService._print_error(response)
示例#5
0
 def request_data(self, sid: SimulationID, vid: VehicleID,
                  request: DataRequest) -> DataResponse:
     """
     Request data of a certain vehicle contained by a certain simulation.
     :param sid: The ID of the simulation the vehicle to request data about is part of.
     :param vid: The ID of the vehicle to get collected data from.
     :param request: The types of data to be requested about the given vehicle. A DataRequest object is build like
     the following:
     request = DataRequest()
     request.request_ids.extend(["id_1", "id_2",..., "id_n"])
     NOTE: You have to use extend(...)! An assignment like request.request_ids = [...] will not work due to the
     implementation of Googles protobuffer.
     :return: The data the simulation collected about the given vehicle. The way of accessing the data is dependant
     on the type of data you requested. To find out how to access the data properly you should set a break point and
     checkout the content of the returned value using a debugger.
     """
     from drivebuildclient.httpUtil import do_get_request
     response = do_get_request(
         self.host, self.port, "/ai/requestData", {
             "request": request.SerializeToString(),
             "sid": sid.SerializeToString(),
             "vid": vid.SerializeToString()
         })
     if response.status == 200:
         result = b"".join(response.readlines())
         data_response = DataResponse()
         data_response.ParseFromString(result)
         return data_response
     else:
         AIExchangeService._print_error(response)
示例#6
0
 def wait_for_simulator_request(
         self, sid: SimulationID,
         vid: VehicleID) -> SimStateResponse.SimState:
     """
     Waits for the simulation with ID sid to request the car with ID vid. This call blocks until the simulation
     requests the appropriate car in the given simulation.
     :param sid: The ID of the simulation the vehicle is included in.
     :param vid: The ID of the vehicle in the simulation to wait for.
     :return: The current state of the simulation at the point when the call to this function returns. The return
     value should be used to check whether the simulation is still running. Another vehicle or the even user may have
     stopped the simulation.
     """
     from drivebuildclient.httpUtil import do_get_request
     response = do_get_request(self.host, self.port,
                               "/ai/waitForSimulatorRequest", {
                                   "sid": sid.SerializeToString(),
                                   "vid": vid.SerializeToString()
                               })
     if response.status == 200:
         result = b"".join(response.readlines())
         sim_state = SimStateResponse()
         sim_state.ParseFromString(result)
         return sim_state.state
     else:
         AIExchangeService._print_error(response)
示例#7
0
 def __init__(self, sid: SimulationID, pickled_test_case: bytes, port: int):
     import dill as pickle
     self.sid = sid
     self._sim_name = "drivebuild_" + sid.sid
     self.serialized_sid = sid.SerializeToString()
     self.pickled_test_case = pickled_test_case
     test_case = pickle.loads(pickled_test_case)
     self.test_name = test_case.name
     self.port = port
     self._sim_server_socket = None
     self._sim_node_client_socket = None
示例#8
0
def run_test_case(
    test_case: TestCase
) -> Tuple[Simulation, Scenario, ExtThread, SimulationID]:
    """
    This method starts the actual simulation in a separate thread.
    Additionally it already calculates and attaches all information that is need by this node and the separate
    thread before calling _start_simulation(...).
    """
    import dill as pickle
    from drivebuildclient import create_client, send_request
    from config import SIM_NODE_PORT, FIRST_SIM_PORT
    sid = SimulationID()
    response = send_request(create_client("localhost", SIM_NODE_PORT),
                            b"generateSid", [])
    sid.ParseFromString(response)
    sim = Simulation(sid, pickle.dumps(test_case),
                     FIRST_SIM_PORT + run_test_case.counter)
    run_test_case.counter += 1  # FIXME Add a lock?
    # Make sure there is no folder of previous tests having the same sid that got not propery removed
    bng_scenario, thread = sim._start_simulation(test_case)

    return sim, bng_scenario, thread, sid
示例#9
0
 def get_status(self, sid: SimulationID) -> str:
     """
     Check the status of the given simulation.
     :param sid: The simulation to get the status of.
     :return: A string representing the status of the simulation like RUNNING, FINISHED or ERRORED.
     """
     from drivebuildclient.httpUtil import do_get_request
     import dill as pickle
     response = do_get_request(self.host, self.port, "/stats/status",
                               {"sid": sid.SerializeToString()})
     if response.status == 200:
         return pickle.loads(b"".join(response.readlines()))
     else:
         AIExchangeService._print_error(response)
         return "Status could not be determined."
示例#10
0
 def control_sim(self, sid: SimulationID,
                 result: TestResult) -> Optional[Void]:
     """
     Force a simulation to end having the given result.
     :param sid: The simulation to control.
     :param result: The test result to be set to the simulation.
     :return: A Void object possibly containing a info message.
     """
     from drivebuildclient.httpUtil import do_get_request
     response = do_get_request(self.host, self.port, "/sim/stop", {
         "sid": sid.SerializeToString(),
         "result": result.SerializeToString()
     })
     if response.status == 200:
         void = Void()
         void.ParseFromString(b"".join(response.readlines()))
         return void
     else:
         AIExchangeService._print_error(response)
示例#11
0
 def get_result(self, sid: SimulationID) -> str:
     """
     Get the test result of the given simulation. This call blocks until the test result of the simulation is known.
     :param sid: The simulation to get the test result of.
     :return: The current test result of the given simulation like SUCCEEDED, FAILED or CANCELLED.
     """
     from drivebuildclient.httpUtil import do_get_request
     import dill as pickle
     from time import sleep
     while True:  # Pseudo do-while-loop
         response = do_get_request(self.host, self.port, "/stats/result",
                                   {"sid": sid.SerializeToString()})
         if response.status == 200:
             result = pickle.loads(b"".join(response.readlines()))
             if result == "UNKNOWN":
                 sleep(1)
             else:
                 return result
         else:
             AIExchangeService._print_error(response)
             return "Result could not be determined."
示例#12
0
 def _handle_main_app_message(action: bytes, data: List[bytes]) -> bytes:
     from google.protobuf.message import DecodeError
     if action == b"runTests":
         user = User()
         try:
             user.ParseFromString(data[1])
             result = _run_tests(data[0], user)
         except DecodeError:
             _logger.exception("Running a test failed since \"" +
                               str(data[1]) +
                               "\" can not be parsed to an User")
             result = SubmissionResult()
             result.message.message = "The user parameter could not be parsed."
     elif action == b"waitForSimulatorRequest":
         sid = SimulationID()
         sid.ParseFromString(data[0])
         vid = VehicleID()
         vid.ParseFromString(data[1])
         result = _wait_for_simulator_request(sid, vid)
     elif action == b"control":
         sid = SimulationID()
         sid.ParseFromString(data[0])
         vid = VehicleID()
         vid.ParseFromString(data[1])
         control = Control()
         control.ParseFromString(data[2])
         result = _control(sid, vid, control)
     elif action == b"requestData":
         sid = SimulationID()
         sid.ParseFromString(data[0])
         vid = VehicleID()
         vid.ParseFromString(data[1])
         request = DataRequest()
         request.ParseFromString(data[2])
         result = _request_data(sid, vid, request)
     elif action == b"requestSocket":
         client = create_client(MAIN_APP_HOST, MAIN_APP_PORT)
         client_thread = Thread(target=process_requests,
                                args=(client, _handle_main_app_message))
         client_thread.daemon = True
         _logger.info("_handle_main_app_message --> " +
                      str(client.getsockname()))
         client_thread.start()
         result = Void()
         result.message = "Connected another client socket to the main app."
     elif action == b"runningTests":
         user = User()
         user.ParseFromString(data[0])
         result = _get_running_tests(user)
     elif action == b"stop":
         sid = SimulationID()
         sid.ParseFromString(data[0])
         test_result = TestResult()
         test_result.ParseFromString(data[1])
         _control_sim(sid, test_result.result, False)
         result = Void()
         result.message = "Stopped simulation " + sid.sid + "."
     else:
         message = "The action \"" + action.decode() + "\" is unknown."
         _logger.info(message)
         result = Void()
         result.message = message
     return result.SerializeToString()
示例#13
0
 def _handle_message(action: bytes, data: List[bytes]) -> bytes:
     from drivebuildclient.aiExchangeMessages_pb2 import Bool
     if action == b"isRunning":
         sid = SimulationID()
         sid.ParseFromString(data[0])
         result = Bool()
         result.value = _is_simulation_running(sid)
     elif action == b"vids":
         sid = SimulationID()
         sid.ParseFromString(data[0])
         result = _get_vids(sid)
     elif action == b"pollSensors":
         sid = SimulationID()
         sid.ParseFromString(data[0])
         result = _poll_sensors(sid)
     elif action == b"verify":
         sid = SimulationID()
         sid.ParseFromString(data[0])
         result = _verify(sid)
     elif action == b"requestAiFor":
         sid = SimulationID()
         sid.ParseFromString(data[0])
         vid = VehicleID()
         vid.ParseFromString(data[1])
         result = _request_ai_for(sid, vid)
     elif action == b"storeVerificationCycle":
         sid = SimulationID()
         sid.ParseFromString(data[0])
         started = Num()
         started.ParseFromString(data[1])
         finished = Num()
         finished.ParseFromString(data[2])
         result = _store_verification_cycle(
             sid, datetime.fromtimestamp(started.num),
             datetime.fromtimestamp(finished.num))
     elif action == b"steps":
         sid = SimulationID()
         sid.ParseFromString(data[0])
         steps = Num()
         steps.ParseFromString(data[1])
         result = Void()
         if _is_simulation_running(sid):
             _get_data(sid).scenario.bng.step(steps.num)
             result.message = "Simulated " + str(
                 steps.num) + " steps in simulation " + sid.sid + "."
         else:
             result.message = "Simulation " + sid.sid + " is not running anymore."
     elif action == b"stop":
         sid = SimulationID()
         sid.ParseFromString(data[0])
         test_result = TestResult()
         test_result.ParseFromString(data[1])
         _control_sim(sid, test_result.result, False)
         result = Void()
     else:
         message = "The action \"" + action.decode() + "\" is unknown."
         _logger.info(message)
         result = Void()
         result.message = message
     return result.SerializeToString()
示例#14
0
from AIExchangeService import AIExchangeService
from drivebuildclient.aiExchangeMessages_pb2 import SimulationID, TestResult

if __name__ == "__main__":
    sid = SimulationID()
    sid.sid = "<ID of simulation>"
    result = TestResult()
    result.result = TestResult.Result.FAILED
    AIExchangeService("localhost", 8383).control_sim(sid, result)