Пример #1
0
class BeamNG_ACC_Test():
    def __init__(self, **kwargs):
        keys = kwargs.keys()
        if "test_controller" in keys:
            self.controller = kwargs.get("test_controller")
        else:
            self.controller = ACC_Test()
        config = BeamNG_Cruise_Control.Config(KP=CC_P,
                                              KI=CC_I,
                                              KD=CC_D,
                                              target=ACC_CAR_SPEED)
        config2 = BeamNG_Cruise_Control.Config(KP=CC_P,
                                               KI=CC_I,
                                               KD=CC_D,
                                               target=FRONT_CAR_SPEED)
        self.PID = BeamNG_Cruise_Control.PID_Controller(config=config)
        self.PID2 = BeamNG_Cruise_Control.PID_Controller(config=config2)

    def setup_bngServer(self):
        # Instantiate BeamNGpy instance running the simulator from the given path,
        if ('BNG_HOME' in os.environ):
            self.bng = BeamNGpy('localhost',
                                64256,
                                home=os.environ['BNG_HOME'])
        else:
            print(
                "WARNING no BNG_HOME is set! Make sure to set BeamNG.research path to research\trunk\ as environment variable (or write the path in the script by yourself)"
            )
            self.bng = BeamNGpy(
                'localhost',
                64256,
                home='C:\\Users\\Ingars\\Beamng-unlimited\\trunk')

    def setup_BeamNG(self):
        # Create a scenario in test map
        self.scenario = Scenario('cruise-control', 'example')

        # Create an ETK800 with the licence plate 'PID'
        self.vehicle = Vehicle('ACC', model='etk800', licence='ACC')

        electrics = Electrics()
        self.vehicle.attach_sensor('electrics',
                                   electrics)  # Cars electric system

        # Add it to our scenario at this position and rotation
        self.scenario.add_vehicle(self.vehicle, pos=ACC_CAR_POS, rot=(0, 0, 0))

        self.vehicle2 = Vehicle('FRONT', model='etk800', licence='FRONT')
        self.vehicle2.attach_sensor('electrics',
                                    electrics)  # Cars electric system
        self.scenario.add_vehicle(self.vehicle2,
                                  pos=FRONT_CAR_POS,
                                  rot=(0, 0, 180))
        # Place files defining our scenario for the simulator to read
        self.scenario.make(self.bng)

        # Launch BeamNG.research

        self.bng.open()

        # Load and start our scenario

        self.bng.load_scenario(self.scenario)
        self.bng.start_scenario()

    def runTest(self):
        self.bng.restart_scenario()
        self.bng.teleport_vehicle(self.vehicle,
                                  pos=ACC_CAR_POS,
                                  rot=(0, 0, 180))
        self.run()

    def run(self):
        self.setupTest()
        wanted_t = ACC_CAR_SPEED
        wanted_d = WANTED_DISTANCE

        soft_brake_d = wanted_d - (wanted_d / 2)

        wanted_d_buffer = wanted_d - (wanted_d / 5)
        # Wanted distance has a buffer of 25%, to compensate holding same constant speed at bigger distance

        deacc_d = wanted_d_buffer + 10
        # +10 meters is buffer for starting to decelerate towards front car speed and wanted distance.
        # the buffer should be calculated dynamically instead to compensate for different speeds
        while self.controller.ended == False:
            start_time = datetime.datetime.now()
            sensors = self.bng.poll_sensors(self.vehicle)
            position = self.vehicle.state['pos']
            position2 = self.vehicle2.state['pos']
            sensors2 = self.bng.poll_sensors(
                self.vehicle2
            )  # replace with self.vehicle.update_vehicle when not using pre-generated coordinates of vehicle to follow

            wheel_speed = sensors['electrics']['values']['wheelspeed']

            distance = self.controller.setDistance(position, position2)

            front_car_speed = self.controller.getFrontCarSpeed(wheel_speed)
            curr_target = self.PID.get_target()
            print("distance: " + str(distance))
            #FORMULA USED for deacceleration = front_car_speed^2 = wheel_speed^2 + (distance-20)*2*a
            #d = (front_car_speed - wheel_speed) / (-0.3 * 2) # 0.3 deacceleration? distance for reducing speed to front cars speed with -0.3 acceleration
            #print("d: " + str(d))
            if distance < 5:  # 5 is manually set as last allowed distance between both cars, will not work good if ACC car is driving too fast. Would be better to calculate it as braking distance.
                print("brake1")
                self.vehicle.control(brake=1)
                self.vehicle.control(throttle=0)
            elif distance < soft_brake_d:
                print("brake1")
                self.vehicle.control(
                    brake=0.1
                )  #Softness of brake could also be calculated dynamically to compensate different speeds
                self.vehicle.control(throttle=0)
            else:
                if distance <= wanted_d_buffer:
                    print("wanted")
                    if front_car_speed > curr_target + 3.5 or front_car_speed < curr_target - 2:  #or front_car_speed < curr_target - 1   // calibrate 3.5 and 2
                        self.PID.change_target(max(front_car_speed, 0))
                elif distance <= deacc_d:
                    a = (front_car_speed - wheel_speed) / (
                        (distance - wanted_d_buffer) * 2)
                    print("a:" + str(a))
                    self.PID.change_target(a + wheel_speed)
                elif curr_target != wanted_t:
                    self.PID.change_target(wanted_t)
                print("throttle1")
                value = self.PID.calculate_throttle(wheel_speed)
                value = min(1, value)
                self.vehicle.control(brake=0)
                self.vehicle.control(throttle=value)
            #PID for front car
            wheel_speed2 = sensors2['electrics']['values']['wheelspeed']
            # print("real front:" + str(wheel_speed2))
            value2 = self.PID2.calculate_throttle(wheel_speed2)
            value2 = min(1, value2)
            self.vehicle2.control(brake=0)
            self.vehicle2.control(throttle=value2)

            elapsed_time = datetime.datetime.now() - start_time
            while (elapsed_time.total_seconds() * 1000) < 100:
                elapsed_time = datetime.datetime.now() - start_time
            elapsed_total = self.controller.calculateElapsed()
            # Change front car speed after 10 seconds and after 20 seconds
            if elapsed_total.total_seconds() > float(10):
                self.PID2.change_target(20)
            if elapsed_total.total_seconds() > float(20):
                self.PID2.change_target(10)
        print("Ending Test")

    def close(self):
        self.bng.close()

    def setupTest(self):
        self.vehicle.update_vehicle()
        self.controller.last_position = self.vehicle.state['pos']
        self.controller.start()
Пример #2
0
class BeamNG_Cruise_Controller_Test():
    def __init__(self, **kwargs):
        keys = kwargs.keys()
        if "test_controller" in keys:
            self.controller = kwargs.get("test_controller")
        else:
            self.controller = PID_Controller_Test()
        if "testing_times" in keys:
            self.testing_times = kwargs.get("testing_times")
        else:
            self.testing_times = 1
        if "test_name" in keys:
            self.test_name = kwargs.get("test_name")
        else:
            self.test_name = "test"
        if "targets" in keys:
            self.targets = kwargs.get("targets")
        else:
            self.targets = [0]

    def setup_bngServer(self):
        # Instantiate BeamNGpy instance running the simulator from the given path,
        if ('BNG_HOME' in os.environ):
            self.bng = BeamNGpy('localhost',
                                64256,
                                home=os.environ['BNG_HOME'])
        else:
            print(
                "WARNING no BNG_HOME is set! Make sure to set BeamNG.research path to research\trunk\ as environment variable (or write the path in the script by yourself)"
            )
            self.bng = BeamNGpy('localhost', 64256, home='')

    def setup_BeamNG(self):
        # Create a scenario in test map
        scenario = Scenario('cruise-control', 'example')

        # Create an ETK800 with the licence plate 'PID'
        self.vehicle = Vehicle('ego_vehicle', model='etk800', licence='PID')

        electrics = Electrics()
        self.vehicle.attach_sensor('electrics',
                                   electrics)  # Cars electric system

        # Add it to our scenario at this position and rotation
        scenario.add_vehicle(self.vehicle,
                             pos=(406.787, 1115.518, 0),
                             rot=(0, 0, 0))

        # Place files defining our scenario for the simulator to read
        scenario.make(self.bng)

        # Launch BeamNG.research

        self.bng.open()

        # Load and start our scenario

        self.bng.load_scenario(scenario)
        self.bng.start_scenario()

    def runTest(self, test_K_values, test_name):
        for test_K_value in test_K_values:
            KP_in, KI_in, KD_in = map(float, test_K_value)

            if KP_in == 0 and KI_in == 0 and KD_in == 0:
                config = Config()
                controller = On_Off_Controller(config=config)
            else:
                config = Config(KP=KP_in, KI=KI_in, KD=KD_in)
                controller = PID_Controller(config=config)
            self.controller.controller = controller
            self.test_name = str(test_name) + "_" + str(KP_in) + "_" + str(
                KI_in) + "_" + str(KD_in)
            self.runTestForPID()

    def runTestForPID(self):
        for speed in self.targets:
            self.controller.setTarget(speed)
            self.controller.setTime(float(30))
            #self.runTestOfType("up_{0}_".format(speed), (406.787, 700.517, 0.214829), (0, 0, 0))
            self.runTestOfType("straight_{0}_".format(speed),
                               (406.787, 715.517, 0.214829), (0, 0, 180))
            #self.runTestOfType("down_{0}_".format(speed), (406.787, 304.896, 100.211), (0, 0, 180))

    def runTestOfType(self, type, pos, rot):
        i = 1
        while i <= self.testing_times:
            self.controller.newLogFile("../logs/" + self.test_name + "_" +
                                       str(type) + "_" + str(i) + ".txt")
            self.bng.restart_scenario()
            self.bng.teleport_vehicle(self.vehicle, pos=pos, rot=rot)
            self.run()
            i += 1

    def run(self):
        self.controller.start()
        while self.controller.ended == False:
            start_time = datetime.datetime.now()
            sensors = self.bng.poll_sensors(self.vehicle)
            wheel_speed = sensors['electrics']['values']['wheelspeed']
            value = self.controller.calculate_speed_with_logs(wheel_speed)
            if value <= 0:
                value = max(-1, value - 0.1) * -1
                self.vehicle.control(brake=value)
                self.vehicle.control(throttle=0)
            else:
                value = min(1, value)
                self.vehicle.control(brake=0)
            self.vehicle.control(throttle=value)
            elapsed_time = datetime.datetime.now() - start_time
            while (elapsed_time.total_seconds() * 1000) < 100:
                elapsed_time = datetime.datetime.now() - start_time
        print("Ending Test")

    def close(self):
        self.bng.close()
Пример #3
0
class ImpactGenerator:
    parts = [
        'etk800_bumper_F',
        'etk800_bumperbar_F',
        'etk800_bumper_R',
        'etk800_fender_L',
        'etk800_fender_R',
        'etk800_hood',
        'etk800_towhitch',
        'etk800_steer',
        'etk800_radiator',
        'etk800_roof_wagon',
        'wheel_F_5',
    ]

    emptyable = {
        'etk800_bumperbar_F',
        'etk800_towhitch',
    }

    wca = {
        'level': 'west_coast_usa',
        'a_spawn': (-270.75, 678, 74.9),
        'b_spawn': (-260.25, 678, 74.9),
        'pole_pos': (-677.15, 848, 75.1),
        'linear_pos_a': (-630, 65, 103.4),
        'linear_pos_b': (-619, 77, 102.65),
        'linear_rot_b': (0, 0, 45.5),
        't_pos_a': (-440, 688, 75.1),
        't_pos_b': (-453, 700, 75.1),
        't_rot_b': (0, 0, 315),
        'ref_pos': (-18, 610, 75),
    }

    smallgrid = {
        'level': 'smallgrid',
        'a_spawn': (-270.75, 678, 0.1),
        'b_spawn': (-260.25, 678, 0.1),
        'pole_pos': (-677.15, 848, 0.1),
        'pole': (-682, 842, 0),
        'linear_pos_a': (-630, 65, 0.1),
        'linear_pos_b': (-619, 77, 0.1),
        'linear_rot_b': (0, 0, 45.5),
        't_pos_a': (-440, 688, 0.1),
        't_pos_b': (-453, 700, 0.1),
        't_rot_b': (0, 0, 315),
        'ref_pos': (321, 321, 0.1),
    }

    def __init__(self,
                 bng_home,
                 output,
                 config,
                 poolsize=2,
                 smallgrid=False,
                 sim_mtx=None,
                 similarity=0.5,
                 random_select=False,
                 single=False):
        self.bng_home = bng_home
        self.output = output
        self.config = config
        self.smallgrid = smallgrid
        self.single = single

        self.impactgen_mats = None
        if smallgrid:
            mats = materialmngr.get_impactgen_materials(bng_home)
            self.impactgen_mats = sorted(list(mats))

        self.poolsize = poolsize
        self.similarity = similarity
        self.sim_mtx = sim_mtx
        self.random_select = random_select

        self.pole_space = None
        self.t_bone_space = None
        self.linear_space = None
        self.nocrash_space = None

        self.post_space = None

        self.total_possibilities = 0

        self.bng = BeamNGpy('localhost', 64256, home=bng_home)

        self.scenario = None

        scenario_props = ImpactGenerator.wca
        if smallgrid:
            scenario_props = ImpactGenerator.smallgrid

        self.vehicle_a = Vehicle('vehicle_a', model='etk800')
        self.vehicle_b = Vehicle('vehicle_b', model='etk800')

        self.scenario = Scenario(scenario_props['level'], 'impactgen')
        self.scenario.add_vehicle(self.vehicle_a,
                                  pos=scenario_props['a_spawn'],
                                  rot=(0, 0, 0))
        self.scenario.add_vehicle(self.vehicle_b,
                                  pos=scenario_props['b_spawn'],
                                  rot=(0, 0, 0))

        self.vehicle_a_parts = defaultdict(set)
        self.vehicle_a_config = None
        self.vehicle_b_config = None

    def generate_colors(self):
        return copy.deepcopy(self.config['colors'])

    def generate_nocrash_space(self, props):
        nocrash_options = []
        for part in ImpactGenerator.parts:  # Vary each configurable part
            nocrash_options.append(self.vehicle_a_parts[part])
        self.nocrash_space = OptionSpace(nocrash_options)

    def generate_pole_space(self, props):
        pole_options = [(False, True)]  # Vehicle facing forward/backward
        pole_options.append(np.linspace(-0.75, 0.75, 5))  # Position offset
        pole_options.append(np.linspace(0.15, 0.5, 4))  # Throttle intensity
        for part in ImpactGenerator.parts:  # Vary each configurable part
            pole_options.append(self.vehicle_a_parts[part])
        self.pole_space = OptionSpace(pole_options)

    def generate_t_bone_space(self, props):
        t_options = [(False, True)]  # Vehicle hit left/right
        t_options.append(np.linspace(-30, 30, 11))  # A rotation offset
        t_options.append(np.linspace(-1.5, 1.5, 5))  # B pos. offset
        t_options.append(np.linspace(0.2, 0.5, 4))  # B throttle
        for part in ImpactGenerator.parts:
            t_options.append(self.vehicle_a_parts[part])
        self.t_bone_space = OptionSpace(t_options)

    def generate_linear_space(self, props):
        linear_options = [(False, True)]  # Vehicle hit front/back
        linear_options.append(np.linspace(-15, 15, 5))  # A rot. offset
        linear_options.append(np.linspace(-1.33, 1.33, 5))  # B pos. offset
        linear_options.append(np.linspace(0.25, 0.5, 4))  # B throttle
        for part in ImpactGenerator.parts:
            linear_options.append(self.vehicle_a_parts[part])
        self.linear_space = OptionSpace(linear_options)

    def get_material_options(self):
        if not self.random_select:
            selected = materialmngr.pick_materials(self.impactgen_mats,
                                                   self.sim_mtx,
                                                   poolsize=self.poolsize,
                                                   similarity=self.similarity)
            if selected is None:
                log.info('Could not find material pool through similarity. '
                         'Falling back to random select.')
        else:
            selected = random.sample(self.impactgen_mats, self.poolsize)

        return selected

    def generate_post_space(self):
        colors = self.generate_colors()
        post_options = []
        post_options.append(self.config['times'])
        if self.smallgrid:
            post_options.append([0])
            post_options.append([0])
        else:
            post_options.append(self.config['clouds'])
            post_options.append(self.config['fogs'])
        post_options.append(colors)
        if self.smallgrid:
            mats = self.get_material_options()
            if mats is not None:
                post_options.append(list(mats))
                post_options.append(list(mats))
        return OptionSpace(post_options)

    def generate_spaces(self):
        props = ImpactGenerator.wca
        if self.smallgrid:
            props = ImpactGenerator.smallgrid

        self.generate_nocrash_space(props)
        self.generate_t_bone_space(props)
        self.generate_linear_space(props)
        self.generate_pole_space(props)

    def scan_parts(self, parts, known=set()):
        with open('out.json', 'w') as outfile:
            outfile.write(json.dumps(parts, indent=4, sort_keys=True))

        for part_type in ImpactGenerator.parts:
            options = parts[part_type]
            self.vehicle_a_parts[part_type].update(options)

    def init_parts(self):
        self.vehicle_a_config = self.vehicle_a.get_part_config()
        self.vehicle_b_config = self.vehicle_b.get_part_config()

        b_parts = self.vehicle_b_config['parts']
        b_parts['etk800_licenseplate_R'] = 'etk800_licenseplate_R_EU'
        b_parts['etk800_licenseplate_F'] = 'etk800_licenseplate_F_EU'
        b_parts['licenseplate_design_2_1'] = 'license_plate_germany_2_1'

        options = self.vehicle_a.get_part_options()
        self.scan_parts(options)

        for k in self.vehicle_a_parts.keys():
            self.vehicle_a_parts[k] = list(self.vehicle_a_parts[k])
            if k in ImpactGenerator.emptyable:
                self.vehicle_a_parts[k].append('')

    def init_settings(self):
        self.bng.set_particles_enabled(False)

        self.generate_spaces()

        log.info('%s pole crash possibilities.', self.pole_space.count)
        log.info('%s T-Bone crash possibilities.', self.t_bone_space.count)
        log.info('%s parallel crash possibilities.', self.linear_space.count)
        log.info('%s no crash possibilities.', self.nocrash_space.count)

        self.total_possibilities = \
            self.pole_space.count + \
            self.t_bone_space.count + \
            self.linear_space.count + \
            self.nocrash_space.count
        log.info('%s total incidents possible.', self.total_possibilities)

    def get_vehicle_config(self, setting):
        parts = dict()
        for idx, part in enumerate(ImpactGenerator.parts):
            parts[part] = setting[idx]
        refwheel = parts['wheel_F_5']
        parts['wheel_R_5'] = refwheel.replace('_F', '_R')

        # Force licence plate to always be German
        parts['etk800_licenseplate_R'] = 'etk800_licenseplate_R_EU'
        parts['etk800_licenseplate_F'] = 'etk800_licenseplate_F_EU'
        parts['licenseplate_design_2_1'] = 'license_plate_germany_2_1'

        config = copy.deepcopy(self.vehicle_a_config)
        config['parts'] = parts
        return config

    def set_annotation_paths(self):
        part_path = os.path.join(self.bng_home, PART_ANNOTATIONS)
        part_path = os.path.abspath(part_path)
        obj_path = os.path.join(self.bng_home, OBJ_ANNOTATIONS)
        obj_path = os.path.abspath(obj_path)

        req = dict(type='ImpactGenSetAnnotationPaths')
        req['partPath'] = part_path
        req['objPath'] = obj_path
        self.bng.send(req)
        resp = self.bng.recv()
        assert resp['type'] == 'ImpactGenAnnotationPathsSet'

    def set_image_properties(self):
        req = dict(type='ImpactGenSetImageProperties')
        req['imageWidth'] = self.config['imageWidth']
        req['imageHeight'] = self.config['imageHeight']
        req['colorFmt'] = self.config['colorFormat']
        req['annotFmt'] = self.config['annotFormat']
        req['radius'] = self.config['cameraRadius']
        req['height'] = self.config['cameraHeight']
        req['fov'] = self.config['fov']

        self.bng.send(req)
        resp = self.bng.recv()
        assert resp['type'] == 'ImpactGenImagePropertiesSet'

    def setup(self):
        self.scenario.make(self.bng)
        log.debug('Loading scenario...')
        self.bng.load_scenario(self.scenario)
        log.debug('Setting steps per second...')
        self.bng.set_steps_per_second(50)
        log.debug('Enabling deterministic mode...')
        self.bng.set_deterministic()
        log.debug('Starting scenario...')
        self.bng.start_scenario()
        log.debug('Scenario started. Sleeping 20s.')
        time.sleep(20)

        self.init_parts()
        self.init_settings()

        log.debug('Setting annotation properties.')
        self.set_annotation_paths()
        self.set_image_properties()

    def settings_exhausted(self):
        return self.t_bone_space.exhausted() and \
            self.linear_space.exhausted() and \
            self.pole_space.exhausted() and \
            self.nocrash_space.exhausted()

    def set_post_settings(self, vid, settings):
        req = dict(type='ImpactGenPostSettings')
        req['ego'] = vid
        req['time'] = settings[0]
        req['clouds'] = settings[1]
        req['fog'] = settings[2]
        req['color'] = settings[3]
        if len(settings) > 4:
            req['skybox'] = settings[4]
        if len(settings) > 5:
            req['ground'] = settings[5]
        self.bng.send(req)
        resp = self.bng.recv()
        assert resp['type'] == 'ImpactGenPostSet'

    def finished_producing(self):
        req = dict(type='ImpactGenOutputGenerated')
        self.bng.send(req)
        resp = self.bng.recv()
        assert resp['type'] == 'ImpactGenZipGenerated'
        return resp['state']

    def produce_output(self, color_name, annot_name):
        while not self.finished_producing():
            time.sleep(0.2)

        req = dict(type='ImpactGenGenerateOutput')
        req['colorName'] = color_name
        req['annotName'] = annot_name
        self.bng.send(req)
        resp = self.bng.recv()
        assert resp['type'] == 'ImpactGenZipStarted'
        'ImpactGenZipStarted'

    def capture_post(self, crash_setting):
        log.info('Enumerating post-crash settings and capturing output.')
        self.bng.switch_vehicle(self.vehicle_a)
        ref_pos = ImpactGenerator.wca['ref_pos']
        if self.smallgrid:
            ref_pos = ImpactGenerator.smallgrid['ref_pos']
        self.bng.teleport_vehicle(self.vehicle_a, ref_pos)
        self.bng.teleport_vehicle(self.vehicle_b, (10000, 10000, 10000))

        self.bng.step(50, wait=True)
        self.bng.pause()

        self.post_space = self.generate_post_space()
        while not self.post_space.exhausted():
            post_setting = self.post_space.sample_new()

            scenario = [[str(s) for s in crash_setting]]
            scenario.append([str(s) for s in post_setting])
            key = str(scenario).encode('ascii')
            key = hashlib.sha512(key).hexdigest()[:30]

            t = int(time.time())
            color_name = '{}_{}_0_image.zip'.format(t, key)
            annot_name = '{}_{}_0_annotation.zip'.format(t, key)
            color_name = os.path.join(self.output, color_name)
            annot_name = os.path.join(self.output, annot_name)

            log.info('Setting post settings.')
            self.set_post_settings(self.vehicle_a.vid, post_setting)
            log.info('Producing output.')
            self.produce_output(color_name, annot_name)

            if self.single:
                break

        self.bng.resume()

    def run_t_bone_crash(self):
        log.info('Running t-bone crash setting.')
        if self.t_bone_space.exhausted():
            log.debug('T-Bone crash setting exhausted.')
            return None

        props = ImpactGenerator.wca
        if self.smallgrid:
            props = ImpactGenerator.smallgrid

        setting = self.t_bone_space.sample_new()
        side, angle, offset, throttle = setting[:4]
        config = setting[4:]
        config = self.get_vehicle_config(config)

        if side:
            angle += 225
        else:
            angle += 45

        pos_a = props['t_pos_a']

        rot_b = props['t_rot_b']
        pos_b = list(props['t_pos_b'])
        pos_b[0] += offset

        req = dict(type='ImpactGenRunTBone')
        req['ego'] = self.vehicle_a.vid
        req['other'] = self.vehicle_b.vid
        req['config'] = config
        req['aPosition'] = pos_a
        req['angle'] = angle
        req['bPosition'] = pos_b
        req['bRotation'] = rot_b
        req['throttle'] = throttle
        log.debug('Sending t-bone crash config.')
        self.bng.send(req)
        log.debug('T-Bone crash response received.')
        resp = self.bng.recv()
        assert resp['type'] == 'ImpactGenTBoneRan'

        return setting

    def run_linear_crash(self):
        log.info('Running linear crash setting.')
        if self.linear_space.exhausted():
            log.debug('Linear crash settings exhausted.')
            return None

        props = ImpactGenerator.wca
        if self.smallgrid:
            props = ImpactGenerator.smallgrid

        setting = self.linear_space.sample_new()
        back, angle, offset, throttle = setting[:4]
        config = setting[4:]
        config = self.get_vehicle_config(config)

        if back:
            angle += 225
        else:
            offset += 1.3
            angle += 45

        pos_a = props['linear_pos_a']

        rot_b = props['linear_rot_b']
        pos_b = list(props['linear_pos_b'])
        pos_b[0] += offset

        req = dict(type='ImpactGenRunLinear')
        req['ego'] = self.vehicle_a.vid
        req['other'] = self.vehicle_b.vid
        req['config'] = config
        req['aPosition'] = pos_a
        req['angle'] = angle
        req['bPosition'] = pos_b
        req['bRotation'] = rot_b
        req['throttle'] = throttle
        log.debug('Sending linear crash config.')
        self.bng.send(req)
        log.debug('Linear crash response received.')
        resp = self.bng.recv()
        assert resp['type'] == 'ImpactGenLinearRan'

        return setting

    def run_pole_crash(self):
        log.info('Running pole crash setting.')
        if self.pole_space.exhausted():
            log.debug('Pole crash settings exhausted.')
            return None

        props = ImpactGenerator.wca
        if self.smallgrid:
            props = ImpactGenerator.smallgrid

        setting = self.pole_space.sample_new()
        back, offset, throttle = setting[:3]
        config = setting[3:]
        config = self.get_vehicle_config(config)

        angle = 45
        if back:
            angle = 225
            offset += 0.85
            throttle = -throttle

        pos = list(props['pole_pos'])
        pos[0] += offset

        req = dict(type='ImpactGenRunPole')
        req['ego'] = self.vehicle_a.vid
        req['config'] = config
        req['position'] = pos
        req['angle'] = angle
        req['throttle'] = throttle
        if self.smallgrid:
            req['polePosition'] = props['pole']
        log.debug('Sending pole crash config.')
        self.bng.send(req)
        log.debug('Got pole crash response.')
        resp = self.bng.recv()
        assert resp['type'] == 'ImpactGenPoleRan'

        return setting

    def run_no_crash(self):
        log.info('Running non-crash scenario.')
        if self.nocrash_space.exhausted():
            return None

        setting = self.nocrash_space.sample_new()
        log.info('Got new setting: %s', setting)

        vehicle_config = self.get_vehicle_config(setting)
        log.info('Got new vehicle config: %s', vehicle_config)

        req = dict(type='ImpactGenRunNonCrash')
        req['ego'] = self.vehicle_a.vid
        req['config'] = vehicle_config
        log.info('Sending Non-Crash request: %s', req)
        self.bng.send(req)
        resp = self.bng.recv()
        assert resp['type'] == 'ImpactGenNonCrashRan'
        log.info('Non-crash finished.')

        return setting

    def run_incident(self, incident):
        log.info('Setting up next incident.')
        self.bng.display_gui_message('Setting up next incident...')
        setting = incident()
        self.capture_post(setting)
        return setting

    def run_incidents(self):
        log.info('Enumerating possible incidents.')
        count = 1

        incidents = [
            self.run_t_bone_crash,
            self.run_linear_crash,
            self.run_pole_crash,
            self.run_no_crash,
        ]

        while not self.settings_exhausted():
            log.info('Running incident %s of %s...', count,
                     self.total_possibilities)
            self.bng.restart_scenario()
            log.info('Scenario restarted.')
            time.sleep(5.0)
            self.vehicle_b.set_part_config(self.vehicle_b_config)
            log.info('Vehicle B config set.')

            incident = incidents[count % len(incidents)]
            if self.run_incident(incident) is None:
                log.info('Ran out of options for: %s', incident)
                incidents.remove(incident)  # Possibility space exhausted

            count += 1

    def run(self):
        log.info('Starting up BeamNG instance.')
        self.bng.open(['impactgen/crashOutput'])
        self.bng.skt.settimeout(1000)
        try:
            log.info('Setting up BeamNG instance.')
            self.setup()
            self.run_incidents()
        finally:
            log.info('Closing BeamNG instance.')
            self.bng.close()
class Simulation(object):

    def __init__(self) -> None:
        super().__init__()

        thread = Thread(target=self._intervene)
        thread.start()

        self.step = 0
        self.dist_driven = 0
        self.done = False
        self.last_action = (0.0, 0.0)
        self.bng = BeamNGpy('localhost', 64257, home=BEAMNG_HOME)
        self.scenario = Scenario('train', 'train', authors='Vsevolod Tymofyeyev',
                                 description='Reinforcement learning')

        self.road = TrainingRoad(ASFAULT_PREFAB)
        self.road.calculate_road_line()

        spawn_point = self.road.spawn_point()
        self.last_pos = spawn_point.pos()
        self.scenario.add_road(self.road.asphalt)
        self.scenario.add_road(self.road.mid_line)
        self.scenario.add_road(self.road.left_line)
        self.scenario.add_road(self.road.right_line)

        self.vehicle = Vehicle('ego_vehicle', model='etk800', licence='RL FTW', color='Red')
        front_camera = Camera(pos=(0, 1.4, 1.8), direction=(0, 1, -0.23), fov=FOV,
                              resolution=(CAMERA_WIDTH, CAMERA_HEIGHT),
                              colour=True, depth=False, annotation=False)
        self.vehicle.attach_sensor("front_camera", front_camera)

        self.scenario.add_vehicle(self.vehicle, pos=spawn_point.pos(), rot=spawn_point.rot())

        self.scenario.make(self.bng)
        prefab_path = self.scenario.get_prefab_path()
        update_prefab(prefab_path)

        self.bng.open()
        self.bng.set_deterministic()
        self.bng.set_steps_per_second(SPS)
        self.bng.load_scenario(self.scenario)
        self.bng.start_scenario()

        # self.bng.hide_hud()
        self.bng.pause()

    def _intervene(self):
        while True:
            a = input()
            self.done = not self.done

    def take_action(self, action):
        steering, throttle = action
        steering = steering.item()
        throttle = throttle.item()
        self.last_action = action
        self.step += 1
        self.vehicle.control(steering=steering, throttle=throttle, brake=0.0)
        self.bng.step(STEPS_INTERVAL)

    def _reward(self, done, dist):
        steering = self.last_action[0]
        throttle = self.last_action[1]
        velocity = self.velocity()  # km/h
        if not done:
            reward = REWARD_STEP + THROTTLE_REWARD_WEIGHT * throttle #- MID_DIST_PENALTY_WEIGHT * dist
        else:
            reward = REWARD_CRASH - CRASH_SPEED_WEIGHT * throttle
        return reward

    def observe(self):
        sensors = self.bng.poll_sensors(self.vehicle)
        image = sensors['front_camera']['colour'].convert("RGB")
        image = np.array(image)
        r = ROI

        # Cut to the relevant region
        image = image[int(r[1]):int(r[1] + r[3]), int(r[0]):int(r[0] + r[2])]

        # Convert to BGR
        state = image[:, :, ::-1]

        #done = self.done
        pos = self.vehicle.state['pos']
        dir = self.vehicle.state['dir']
        self.refresh_dist(pos)
        self.last_pos = pos
        dist = self.road.dist_to_center(self.last_pos)
        #velocity = self.velocity()
        done = dist > MAX_DIST #or velocity > MAX_VELOCITY
        reward = self._reward(done, dist)

        return state, reward, done, {}

    def velocity(self):
        state = self.vehicle.state
        velocity = np.linalg.norm(state["vel"])
        return velocity * 3.6

    def position(self):
        return self.vehicle.state["pos"]

    def refresh_dist(self, pos):
        pos = np.array(pos)
        last_pos = np.array(self.last_pos)
        dist = np.linalg.norm(pos - last_pos)
        self.dist_driven += dist

    def close_connection(self):
        self.bng.close()

    def reset(self):
        self.vehicle.control(throttle=0, brake=0, steering=0)
        self.bng.poll_sensors(self.vehicle)

        self.dist_driven = 0
        self.step = 0
        self.done = False

        current_pos = self.vehicle.state['pos']
        closest_point = self.road.closest_waypoint(current_pos)
        #closest_point = self.road.random_waypoint()
        self.bng.teleport_vehicle(vehicle=self.vehicle, pos=closest_point.pos(), rot=closest_point.rot())
        self.bng.pause()

    # TODO delete
    def wait(self):
        from client.aiExchangeMessages_pb2 import SimStateResponse
        return SimStateResponse.SimState.RUNNING
Пример #5
0
def launch(beamNGPath, car1, car2, speed_car2):
    crash = False
    dist_2car = 20
    speed_car2 = int(speed_car2)
    bng = BeamNGpy('localhost', 64256, beamNG_path)
    #bng = BeamNGpy('localhost', 64256, home='D:/BeamNGReasearch/Unlimited_Version/trunk')

    scenario = Scenario('GridMap', 'example')

    # Create an ETK800 with the licence plate 'PYTHON'
    vehicle1 = Vehicle('ego_vehicle',
                       model='etk800',
                       licence='PYTHON',
                       color='Red')
    vehicle2 = Vehicle('vehicle',
                       model='etk800',
                       licence='CRASH',
                       color='Blue')

    electrics1 = Electrics()
    electrics2 = Electrics()
    vehicle1.attach_sensor('electrics1', electrics1)
    vehicle2.attach_sensor('electrics2', electrics2)

    #position to try drive then teleport
    #-365.2436828613281, -214.7460479736328, 1.2118444442749023], [0.9762436747550964, 0.20668958127498627, 0.0650215595960617]]
    #[[-362.4477844238281, -214.16226196289062, 1.32931387424469], [0.9824153780937195, 0.1852567195892334, 0.023236412554979324]]

    pos2 = (25.75335693359375, -127.78406524658203, 0.2072899490594864)
    pos1 = (-88.8136978149414, -261.0204162597656, 0.20253072679042816)

    #pos_tel1 = (53.35311508178711, -139.84017944335938, 0.20729705691337585)           #change this
    #pos_tel2 = (75.94310760498047, -232.62135314941406, 0.20568031072616577)            #change this
    pos_tel1 = car1[0]
    pos_tel2 = car2[0]

    rot2 = (0.9298766851425171, -0.36776003241539, 0.009040255099534988)
    rot1 = (-0.9998571872711182, 0.016821512952446938, -0.0016229493776336312)
    # rot_tel1= (0.8766672611236572, -0.4810631573200226, 0.005705998744815588)         #change this
    # rot_tel2 = (-0.896364688873291, -0.4433068335056305, -0.0030648468527942896)       #change this
    rot_tel1 = car1[1]
    rot_tel2 = car2[1]

    #initial postion of two car.
    # run 2cars on particular road until they reach particular speed which satisfies the condisiton of the given testcase
    scenario.add_vehicle(vehicle1, pos=pos1, rot=rot1)
    scenario.add_vehicle(vehicle2, pos=pos2, rot=rot2)

    scenario.make(bng)

    # Launch BeamNG.research
    bng.open(launch=True)

    try:
        bng.load_scenario(scenario)
        bng.start_scenario()

        vehicle1.ai_set_speed(10, mode='set')
        vehicle1.ai_set_mode('span')

        vehicle2.ai_set_speed(speed_car2,
                              mode='set')  ##change this param of speed
        vehicle2.ai_set_mode('chase')
        sys_output.print_sub_tit("Initial Position and rotation of car")
        print("\nInitial  Position and rotation of car1  %s %s  " %
              (pos1, rot1))
        print("\nInitial  Position and rotation of car2  %s %s  " %
              (pos2, rot2))
        sys_output.print_sub_tit(
            "\n when speed of car 1 rearch 10 and speed car 2 reach %s. Two cars are teleport to new locations."
            % (speed_car2))
        for _ in range(450):
            time.sleep(0.1)
            vehicle1.update_vehicle(
            )  # Synchs the vehicle's "state" variable with the simulator
            vehicle2.update_vehicle()
            sensors1 = bng.poll_sensors(
                vehicle1
            )  # Polls the data of all sensors attached to the vehicle
            sensors2 = bng.poll_sensors(vehicle2)

            speed1 = sensors1['electrics1']['values']['wheelspeed']
            speed2 = sensors2['electrics2']['values']['wheelspeed']
            print("speed of car 1", speed1)
            print("speed of car 2", speed2)
            #print([vehicle1.state['pos'],vehicle1.state['dir']])
            if speed1 > 9 and speed2 > speed_car2 - 1:  #change speed here
                bng.teleport_vehicle(vehicle1, pos_tel1, rot_tel1)
                bng.teleport_vehicle(vehicle2, pos_tel2, rot_tel2)
                sys_output.print_sub_tit("Teleport 2 car to new location")
                print("\n  Car1 : " + str(pos_tel1) + ", " + str(rot_tel1))
                print("\n  Car2 : " + str(pos_tel2) + ", " + str(rot_tel2))
                print("\n  Distance between two cars: " +
                      str(distance.euclidean(pos_tel1, pos_tel2)))
                break

            # if speed > 19:
            # bng.teleport_vehicle(vehicle1,pos_tel,rot_tel )
            # break

        for _ in range(100):
            #pos1 = []
            time.sleep(0.1)
            vehicle1.update_vehicle(
            )  # Synchs the vehicle's "state" variable with the simulator
            vehicle2.update_vehicle()
            sensors1 = bng.poll_sensors(
                vehicle1
            )  # Polls the data of all sensors attached to the vehicle
            sensors2 = bng.poll_sensors(vehicle2)

            speed1 = sensors1['electrics1']['values']['wheelspeed']
            speed2 = sensors2['electrics2']['values']['wheelspeed']

            #pos1.append(vehicle1.state['pos'])
            #pos2.append(vehicle2.state['pos'])

            dist_2car = distance.euclidean(vehicle1.state['pos'],
                                           vehicle2.state['pos'])
            if dist_2car < 5:  #or int(speed2)== 0 :
                crash = True
                print(
                    "\n  Failed because distance of two cars are less than 5")
                break
            print("\n speed1 %s, speed2: %s, distance: %s" %
                  (speed1, speed2, dist_2car))
            if int(speed2) == 0:
                print("\n  Pass because car2 stoped")
                break

        bng.stop_scenario()
        bng.close()
    finally:
        bng.close()

    return crash