示例#1
0
文件: rule.py 项目: SocialCars/colmto
    def __init__(self, bounding_box=BoundingBox(Position(0.0, 0), Position(100.0, 1)),
                 outside=False, subrules=tuple(), subrule_operator=RuleOperator.ANY):
        '''
        Initialisation

        :param bounding_box: BoundingBox, can be represented as a tuple, i.e. ((x1,y1),(x2,y2))
        :param outside: True|False, apply to vehicles outside (or resp. inside) of the bounding box (default: False -> inside)
        :param subrules: List of sub-rules
        :param subrule_operator: Rule operator of RuleOperator enum for applying sub-rules ANY|ALL

        '''

        SUMOPositionRule.__init__(self, bounding_box=bounding_box, outside=outside)
        ExtendableSUMORule.__init__(self, subrules=subrules, subrule_operator=subrule_operator)
示例#2
0
文件: rule.py 项目: SocialCars/colmto
    def __init__(self, bounding_box=BoundingBox(Position(0.0, 0), Position(100.0, 1)), outside=False):
        '''
        Initialisation.

        :param bounding_box: BoundingBox, can be represented as a tuple, i.e. ((x1,y1),(x2,y2))
        :param outside: True|False, apply to vehicles outside (or resp. inside) of the bounding box (default: False -> inside)

        '''

        super().__init__()
        assert BoundingBox(*bounding_box).p1.x <= BoundingBox(*bounding_box).p2.x
        assert BoundingBox(*bounding_box).p1.y <= BoundingBox(*bounding_box).p2.y
        self._bounding_box = BoundingBox(*bounding_box)
        self._outside = bool(outside)
示例#3
0
    def start_position(self, start_position: Position):
        '''
        Include the initial position in calculations, as SUMO tends to put vehicles at positions > 0 in their 0th time step.

        :param start_position_x: start position on x axis
        '''
        self._properties['start_position'] = Position(*start_position)
示例#4
0
    def start_position(self) -> Position:
        '''
        Include the initial position in calculations, as SUMO tends to put vehicles at positions > 0 in their 0th time step.

        :return: start position
        '''
        return Position(*self._properties.get('start_position'))
示例#5
0
    def test_basevehicle(self):
        '''
        Test BaseVehicle class
        '''

        # test default values
        l_basevehicle = colmto.environment.vehicle.BaseVehicle()

        self.assertEqual(l_basevehicle.speed, 0.0)
        self.assertEqual(l_basevehicle.position, Position(0.0, 0))

        # test custom values
        l_basevehicle = colmto.environment.vehicle.BaseVehicle()
        l_basevehicle._properties['position'] = Position(23.0, 0)  # pylint: disable=protected-access
        l_basevehicle._properties['speed'] = 12.1  # pylint: disable=protected-access

        self.assertEqual(l_basevehicle.speed, 12.1)
        self.assertEqual(l_basevehicle.position, Position(23.0, 0))
        self.assertEqual(l_basevehicle.properties.get('position'),
                         Position(23.0, 0))
        self.assertEqual(l_basevehicle.properties.get('speed'), 12.1)
示例#6
0
    def test_update(self):
        '''Test update'''
        l_sumovehicle = colmto.environment.vehicle.SUMOVehicle(
            environment={
                'gridlength': 200,
                'gridcellwidth': 4
            },
            speed_max=15,
            vtype_sumo_cfg={'dsat_threshold': 0.2})

        self.assertEqual(l_sumovehicle.dsat_threshold, 0.2)
        self.assertEqual(l_sumovehicle.speed_max, 15)
        self.assertEqual(l_sumovehicle.dissatisfaction, 0.0)
        l_sumovehicle._properties['position'] = (0, 0)
        l_sumovehicle.start_time = 0

        l_sumovehicle.update(position=Position(15000, 0),
                             lane_index=1,
                             speed=15,
                             time_step=1000)

        self.assertAlmostEqual(l_sumovehicle.dissatisfaction, 0.0, places=4)

        self.assertEqual(l_sumovehicle.position, Position(15000, 0))
        self.assertEqual(
            l_sumovehicle.speed,  # pylint: disable=protected-access
            15)
        self.assertEqual(
            l_sumovehicle.grid_position,  # pylint: disable=protected-access
            GridPosition(round(15000 / 4) - 1, -1))
        self.assertEqual(
            l_sumovehicle.time_step,  # pylint: disable=protected-access
            1000)

        l_sumovehicle.update(position=Position(12500, 0),
                             lane_index=0,
                             speed=12,
                             time_step=1000)

        self.assertAlmostEqual(l_sumovehicle.dissatisfaction, .5, places=4)
示例#7
0
    def test_sumo_cse(self):
        '''
        Test SumoCSE class
        '''
        self.assertIsInstance(
            colmto.cse.cse.SumoCSE(
                SimpleNamespace(loglevel='debug',
                                quiet=False,
                                logfile='foo.log',
                                writefulloccupancies=False)),
            colmto.cse.cse.SumoCSE)

        l_rule_speed = colmto.cse.rule.SUMOMinimalSpeedRule(80.)

        l_rule_outside_position = colmto.cse.rule.SUMOPositionRule(
            bounding_box=((0., 0), (64.0, 1)), outside=True)

        l_sumo_cse = colmto.cse.cse.SumoCSE().add_rule(
            l_rule_outside_position).add_rule(l_rule_speed)

        self.assertIsInstance(l_sumo_cse, colmto.cse.cse.SumoCSE)
        self.assertIsInstance(l_sumo_cse.rules, frozenset)
        self.assertIn(l_rule_speed, l_sumo_cse.rules)
        self.assertIn(l_rule_outside_position, l_sumo_cse.rules)

        self.assertIs(l_sumo_cse._traci, None)  # pylint: disable=protected-access
        l_sumo_cse.traci('foo')
        self.assertEqual(l_sumo_cse._traci, 'foo')  # pylint: disable=protected-access
        self.assertIs(l_sumo_cse.traci(None), l_sumo_cse)

        with self.assertRaises(TypeError):
            l_sumo_cse.add_rule('foo')

        l_vehicles = [
            colmto.environment.vehicle.SUMOVehicle(
                environment={
                    'gridlength': 200,
                    'gridcellwidth': 4
                },
                speed_max=numpy.random.randint(0, 250)) for _ in range(1000)
        ]

        for i_vehicle in l_vehicles:
            i_vehicle._properties['position'] = Position(
                numpy.random.randint(0, 120), numpy.random.randint(0, 1))  # pylint: disable=protected-access

        l_sumo_cse.apply(l_vehicles)

        for i_vehicle in l_vehicles:
            if 0 <= i_vehicle.position.x <= 64.0 and 0 <= i_vehicle.position.y <= 1 and \
                    i_vehicle.speed_max >= 80.0:
                self.assertEqual(i_vehicle.vehicle_class,
                                 colmto.cse.rule.SUMORule.allowed_class_name())
            else:
                self.assertEqual(
                    i_vehicle.vehicle_class,
                    colmto.cse.rule.SUMORule.disallowed_class_name())

        self.assertEqual(
            len(colmto.cse.cse.SumoCSE().add_rules_from_cfg({}).rules), 0)

        l_sumo_cse = colmto.cse.cse.SumoCSE().add_rules_from_cfg([{
            'type':
            'ExtendableSUMOPositionRule',
            'args': {
                'bounding_box': ((1350., -2.), (2500., 2.))
            },
            'subrule_operator':
            'ANY',
            'subrules': [{
                'type': 'SUMOMinimalSpeedRule',
                'args': {
                    'minimal_speed': 85 / 3.6
                },
            }]
        }])

        self.assertIsInstance(
            tuple(l_sumo_cse.rules)[0],
            colmto.cse.rule.ExtendableSUMOPositionRule)

        l_rule_speed = colmto.cse.rule.SUMOMinimalSpeedRule.from_configuration(
            {
                'type': 'SUMOMinimalSpeedRule',
                'args': {
                    'minimal_speed': 30 / 3.6
                }
            })

        l_sumo_cse.add_rule(l_rule_speed)

        self.assertIn(l_rule_speed, l_sumo_cse.rules)
示例#8
0
    def __init__(self,
                 environment: dict,
                 vehicle_type: str = None,
                 vtype_sumo_cfg: dict = None,
                 speed_deviation: float = 0.0,
                 sigma: float = 0.0,
                 speed_max: float = 0.0,
                 cooperation_probability: typing.Union[None, float] = None):
        '''
        Initialisation.

        :type environment: dict
        :param environment: environment
        :type vehicle_type: str
        :param vehicle_type: SUMO vehicle type
        :type vtype_sumo_cfg: dict
        :param vtype_sumo_cfg: (optional) SUMO config
        :type speed_deviation: float
        :param speed_deviation: speed deviation (Krauss driver model)
        :type sigma: float
        :param sigma: sigma (Krauss driver model)
        :type speed_max: float
        :param speed_max: maximum desired or capable speed of vehicle
        :type cooperation_probability: float
        :param cooperation_probability: disposition for cooperative driving with :math:`p\in [0,1]\cup \{None\}`. :math:`p=1` or `None` means always cooperative (default), :math:`p=0` always uncooperative

        '''

        super().__init__()

        if isinstance(vtype_sumo_cfg, dict):
            self._properties.update(vtype_sumo_cfg)

        self._properties.update({
            'colour':
            Colour(red=255, green=255, blue=0, alpha=255),
            'normal_colour':
            Colour(red=255, green=255, blue=0, alpha=255),
            'start_time':
            0.0,
            'start_position':
            Position(x=0.0, y=0.0),
            'speedDev':
            speed_deviation,
            'sigma':
            sigma,
            'maxSpeed':
            speed_max,
            'vType':
            vehicle_type,
            'vClass':
            colmto.cse.rule.SUMORule.allowed_class_name(),
            'grid_position':
            Position(x=0, y=0),
            'time_step':
            0.0,
            'travel_time':
            0.0,
            'dissatisfaction':
            0.0,
            'cooperation_disposition':
            VehicleDisposition.COOPERATIVE if not cooperation_probability else
            VehicleDisposition.choose(cooperation_probability)
        })

        self._environment = environment

        # prepare grid-based series using OrderedDicts to maintain the order of keys
        self._grid_based_series_dict = {
            i_metric.value: OrderedDict()
            for i_metric in StatisticSeries.GRID.metrics()
        }
示例#9
0
 def __init__(self):
     '''Initialisation'''
     self._properties = {'position': Position(x=0.0, y=0.0), 'speed': 0.0}
示例#10
0
    def update(self, position: Position, lane_index: int, speed: float,
               time_step: float) -> BaseVehicle:
        '''
        Update current properties of vehicle providing data acquired from TraCI call.

        For the grid cell the vehicle is in, take the global position in x-direction divided by grid
        cell size and int-rounded. For the y-coordinate take the lane index.

        :note: The cell width can be set via 'gridcellwidth' in the run config.

        :param position: tuple TraCI provided position
        :param lane_index: int TraCI provided lane index
        :param speed: float TraCI provided speed
        :param time_step: float TraCI provided time step
        :return: future Vehicle reference

        '''

        # update current vehicle properties
        l_position = Position(*position)
        assert l_position.x >= 0 and l_position.y >= 0
        self._properties['position'] = l_position
        self._properties['grid_position'] = l_position.gridified(
            width=self._environment.get('gridcellwidth'))
        assert float(speed) >= 0
        self._properties['speed'] = float(speed)
        assert float(time_step) >= 0
        self._properties['time_step'] = float(time_step)
        assert float(time_step) >= self.start_time
        self._properties['travel_time'] = float(time_step) - self.start_time
        assert int(lane_index) in (0, 1)
        self._properties['lane_index'] = int(lane_index)

        # vehicle/generic optimal travel time: round positions of division as SUMO reports positions with reduced
        # accuracy (2 significant figures) to avoid negative travel time losses.
        l_generic_optimal_travel_time = round(self.position.x / self.speed_max,
                                              2)

        # Vehicle optimal travel time: include, i.e. substract the start_position as SUMO puts
        # vehicles at lane positions greater than 0 in their first active time step if they started
        # between the previous and current global (runtime) time step.
        l_vehicle_optimal_travel_time = round(
            (self.position.x - self.start_position.x) / self.speed_max, 2)
        l_vehicle_time_loss = self.travel_time - l_vehicle_optimal_travel_time
        assert l_vehicle_time_loss >= 0

        self._properties[
            'dissatisfaction'] = colmto.common.model.dissatisfaction(
                time_loss=l_vehicle_time_loss,
                optimal_travel_time=l_generic_optimal_travel_time,
                time_loss_threshold=self.dsat_threshold)
        assert 0 <= self.dissatisfaction <= 1

        # update data series based on grid cell
        self._grid_based_series_dict.get(
            Metric.TIME_STEP.value)[(Metric.TIME_STEP.value,
                                     self.grid_position.x)] = float(time_step)
        self._grid_based_series_dict.get(
            Metric.POSITION_Y.value)[(Metric.POSITION_Y.value,
                                      self.grid_position.x)] = self.position.y
        self._grid_based_series_dict.get(Metric.GRID_POSITION_Y.value)[(
            Metric.GRID_POSITION_Y.value,
            self.grid_position.x)] = self.grid_position.y
        self._grid_based_series_dict.get(Metric.DISSATISFACTION.value)[(
            Metric.DISSATISFACTION.value,
            self.grid_position.x)] = self.dissatisfaction
        self._grid_based_series_dict.get(Metric.TRAVEL_TIME.value)[(
            Metric.TRAVEL_TIME.value, self.grid_position.x)] = self.travel_time
        self._grid_based_series_dict.get(Metric.TIME_LOSS.value)[(
            Metric.TIME_LOSS.value,
            self.grid_position.x)] = l_vehicle_time_loss
        self._grid_based_series_dict.get(Metric.RELATIVE_TIME_LOSS.value)[(
            Metric.RELATIVE_TIME_LOSS.value, self.grid_position.x
        )] = l_vehicle_time_loss / l_generic_optimal_travel_time if l_generic_optimal_travel_time > 0 else 0
        self._grid_based_series_dict.get(
            Metric.LANE_INDEX.value)[(Metric.LANE_INDEX.value,
                                      self.grid_position.x)] = self.lane

        return self
示例#11
0
    def test_sumovehicle(self):
        '''
        Test SUMOVehicle class.
        '''

        # test default values
        l_sumovehicle = colmto.environment.vehicle.SUMOVehicle(
            environment={
                'gridlength': 200,
                'gridcellwidth': 4
            })
        self.assertEqual(l_sumovehicle.speed_max, 0.0)
        self.assertEqual(l_sumovehicle.speed, 0.0)  # pylint: disable=protected-access
        self.assertEqual(l_sumovehicle.position, Position(0.0, 0))
        self.assertEqual(l_sumovehicle.vehicle_type, VehicleType.UNDEFINED)
        self.assertEqual(l_sumovehicle.colour, Colour(255, 255, 0, 255))
        self.assertEqual(l_sumovehicle.time_step, 0.0)
        l_sumovehicle._properties['time_step'] = 42.1  # pylint: disable=protected-access
        self.assertEqual(l_sumovehicle.time_step, 42.1)
        self.assertIsInstance(
            l_sumovehicle.properties.get('cooperation_disposition'),
            VehicleDisposition)
        self.assertIs(l_sumovehicle.properties.get('cooperation_disposition'),
                      VehicleDisposition.COOPERATIVE)
        # test custom values
        l_sumovehicle = colmto.environment.vehicle.SUMOVehicle(
            speed_max=27.777,
            speed_deviation=1.2,
            environment={
                'gridlength': 200,
                'gridcellwidth': 4
            },
            vehicle_type='passenger',
            vtype_sumo_cfg={
                'length': 3.00,
                'minGap': 2.50
            })
        l_sumovehicle._properties['position'] = Position(42.0, 0)
        l_sumovehicle.normal_colour = (128, 64, 255, 255)
        l_sumovehicle.start_time = 13
        self.assertEqual(l_sumovehicle.start_position, Position(0.0, 0.0))
        l_sumovehicle.start_position = Position(1.2, 3.4)
        self.assertEqual(l_sumovehicle.start_position.x, 1.2)
        self.assertEqual(l_sumovehicle.start_position.y, 3.4)
        self.assertEqual(l_sumovehicle.start_position.gridified(2).x, 0)
        self.assertEqual(l_sumovehicle.start_position.gridified(2).y, 1)
        self.assertEqual(l_sumovehicle.start_position, Position(1.2, 3.4))

        self.assertEqual(l_sumovehicle.speed_max, 27.777)
        self.assertEqual(l_sumovehicle.position, Position(42.0, 0))
        self.assertEqual(l_sumovehicle.vehicle_type, VehicleType.PASSENGER)
        self.assertEqual(l_sumovehicle.normal_colour,
                         Colour(128, 64, 255, 255))
        self.assertEqual(l_sumovehicle.start_time, 13)
        self.assertEqual(l_sumovehicle.grid_position, GridPosition(0, 0))

        l_sumovehicle._properties['grid_position'] = GridPosition(1, 2)  # pylint: disable=protected-access

        self.assertEqual(l_sumovehicle.grid_position, GridPosition(1, 2))
        self.assertEqual(l_sumovehicle.properties.get('grid_position'),
                         GridPosition(1, 2))
        self.assertEqual(l_sumovehicle.travel_time, 0.0)