Exemple #1
0
    def generate_cfg(self, net_params):
        """Generates .sumo.cfg files using net files and netconvert.

        This includes files such as the routes vehicles can traverse and the
        view settings of the gui (whether the gui is used or not). The
        background of the gui is set here to be grey, with RGB values:
        (100, 100, 100).

        Parameters
        ----------
        net_params: NetParams type
            see flow/core/params.py
        """
        start_time = 0
        end_time = None

        self.roufn = "%s.rou.xml" % self.name
        addfn = "%s.add.xml" % self.name
        cfgfn = "%s.sumo.cfg" % self.name
        guifn = "%s.gui.cfg" % self.name

        # specify routes vehicles can take
        self.rts = self.specify_routes(net_params)

        add = makexml("additional",
                      "http://sumo.dlr.de/xsd/additional_file.xsd")
        for (edge, route) in self.rts.items():
            add.append(E("route", id="route%s" % edge, edges=" ".join(route)))

        printxml(add, self.cfg_path + addfn)

        gui = E("viewsettings")
        gui.append(E("scheme", name="real world"))
        gui.append(
            E("background",
              backgroundColor="100,100,100",
              showGrid="0",
              gridXSize="100.00",
              gridYSize="100.00"))
        printxml(gui, self.cfg_path + guifn)

        cfg = makexml("configuration",
                      "http://sumo.dlr.de/xsd/sumoConfiguration.xsd")

        logging.debug(self.netfn)

        cfg.append(
            self._inputs(self.name,
                         net=self.netfn,
                         add=addfn,
                         rou=self.roufn,
                         gui=guifn))
        t = E("time")
        t.append(E("begin", value=repr(start_time)))
        if end_time:
            t.append(E("end", value=repr(end_time)))
        cfg.append(t)

        printxml(cfg, self.cfg_path + cfgfn)
        return cfgfn
Exemple #2
0
    def generate_cfg(self, net_params):
        """
        Generates .sumo.cfg files using net files and netconvert.
        Requires:
        num_cars: Number of cars to seed the simulation with
           max_speed: max speed of cars
           OR
        type_list: List of types of cars to seed the simulation with

        start_time: time to start the simulation
        end_time: time to end the simulation
        """
        start_time = 0
        end_time = None

        self.roufn = "%s.rou.xml" % self.name
        addfn = "%s.add.xml" % self.name
        cfgfn = "%s.sumo.cfg" % self.name
        guifn = "%s.gui.cfg" % self.name

        # specify routes vehicles can take
        self.rts = self.specify_routes(net_params)

        # TODO: add functionality for multiple routes (such as Braess)
        add = makexml("additional",
                      "http://sumo.dlr.de/xsd/additional_file.xsd")
        for (edge, route) in self.rts.items():
            add.append(E("route", id="route%s" % edge, edges=" ".join(route)))

        # specify (optional) rerouting actions
        rerouting = self.specify_rerouters(net_params)

        if rerouting is not None:
            for rerouting_params in rerouting:
                add.append(self._rerouter(rerouting_params["name"],
                                          rerouting_params["from"],
                                          rerouting_params["route"]))

        printxml(add, self.cfg_path + addfn)

        gui = E("viewsettings")
        gui.append(E("scheme", name="real world"))
        printxml(gui, self.cfg_path +guifn)

        cfg = makexml("configuration",
                      "http://sumo.dlr.de/xsd/sumoConfiguration.xsd")

        logging.debug(self.netfn)

        cfg.append(self._inputs(self.name, net=self.netfn, add=addfn,
                                rou=self.roufn, gui=guifn))
        t = E("time")
        t.append(E("begin", value=repr(start_time)))
        if end_time:
            t.append(E("end", value=repr(end_time)))
        cfg.append(t)

        printxml(cfg, self.cfg_path + cfgfn)
        return cfgfn
Exemple #3
0
    def make_routes(self):
        """Generate .rou.xml files using net files and netconvert.

        This file specifies the sumo-specific properties of vehicles with
        similar types, and well as the inflows of vehicles.
        """
        vehicles = self.network.vehicles
        routes = makexml('routes', 'http://sumo.dlr.de/xsd/routes_file.xsd')

        # add the types of vehicles to the xml file
        for params in vehicles.types:
            type_params_str = {
                key: str(params['type_params'][key])
                for key in params['type_params']
            }
            routes.append(E('vType', id=params['veh_id'], **type_params_str))

        # add the inflows from various edges to the xml file
        if self.network.net_params.inflows is not None:
            total_inflows = self.network.net_params.inflows.get()
            for inflow in total_inflows:
                for key in inflow:
                    if not isinstance(inflow[key], str):
                        inflow[key] = repr(inflow[key])
                    if key == 'edge':
                        inflow['route'] = 'route{}'.format(inflow['edge'])
                        del inflow['edge']
                routes.append(_flow(**inflow))

        printxml(routes, self.cfg_path + self.roufn)
Exemple #4
0
    def make_routes(self, scenario, initial_config):
        """Generates .rou.xml files using net files and netconvert.

        This file specifies the sumo-specific properties of vehicles with
        similar types, and well as the starting positions of vehicles. The
        starting positions, however, may be modified in real-time (e.g. during
        an environment reset).

        Parameters
        ----------
        scenario: Scenario type
            scenario class calling this method. This contains information on
            the properties and initial states of vehicles in the network.
        initial_config: InitialConfig type
            see flow/core/params.py
        """
        vehicles = scenario.vehicles
        routes = makexml("routes", "http://sumo.dlr.de/xsd/routes_file.xsd")

        # add the types of vehicles to the xml file
        for vtype, type_params in vehicles.types:
            type_params_str = {
                key: str(type_params[key])
                for key in type_params
            }
            routes.append(E("vType", id=vtype, **type_params_str))

        self.vehicle_ids = vehicles.get_ids()

        if initial_config.shuffle:
            random.shuffle(self.vehicle_ids)

        # add the initial positions of vehicles to the xml file
        positions = initial_config.positions
        lanes = initial_config.lanes
        for i, veh_id in enumerate(self.vehicle_ids):
            veh_type = vehicles.get_state(veh_id, "type")
            edge, pos = positions[i]
            lane = lanes[i]
            type_depart_speed = vehicles.get_initial_speed(veh_id)
            routes.append(
                self._vehicle(veh_type,
                              "route" + edge,
                              depart="0",
                              id=veh_id,
                              color="1,1,1",
                              departSpeed=str(type_depart_speed),
                              departPos=str(pos),
                              departLane=str(lane)))

        # add the in-flows from various edges to the xml file
        if self.net_params.in_flows is not None:
            total_inflows = self.net_params.in_flows.get()
            for inflow in total_inflows:
                for key in inflow:
                    if not isinstance(inflow[key], str):
                        inflow[key] = repr(inflow[key])
                routes.append(self._flow(**inflow))

        printxml(routes, self.cfg_path + self.roufn)
Exemple #5
0
    def make_routes(self, scenario, initial_config):

        vehicles = scenario.vehicles
        type_list = vehicles.types
        if vehicles.num_vehicles > 0:
            routes = makexml("routes", "http://sumo.dlr.de/xsd/routes_file.xsd")

            # add the types of vehicles to the xml file
            for veh_type in vehicles.types:
                routes.append(E("vType", id=veh_type, minGap="0", accel="100",
                                decel="100"))

            self.vehicle_ids = vehicles.get_ids()

            if initial_config.shuffle:
                random.shuffle(self.vehicle_ids)

            # add the initial positions of vehicles to the xml file
            positions = initial_config.positions
            lanes = initial_config.lanes
            for i, id in enumerate(self.vehicle_ids):
                veh_type = vehicles.get_state(id, "type")
                edge, pos = positions[i]
                lane = lanes[i]
                indx_type = [i for i in range(len(type_list)) if type_list[i] == veh_type][0]
                type_depart_speed = vehicles.get_initial_speed(id)
                routes.append(self._vehicle(
                    veh_type, "route" + edge, depart="0", id=id,
                    color="1,0.0,0.0", departSpeed=str(type_depart_speed),
                    departPos=str(pos), departLane=str(lane)))

            printxml(routes, self.cfg_path + self.roufn)
def GenerateXMLs(filepath="/home/mesto/flow/MyTests/flows.xml"):
    flows = makexml('routes', 'http://sumo.dlr.de/xsd/routes_file.xsd')
    flows.append(
        CreateVTypeElem('human', '2.6', '4.5', '0.5', '70', '2.5', '0.0'))

    flows.append(
        CreateFlowElem('121304377#0', 'flow_0', '1', '900', '2156', 'human',
                       '28.3'))
    flows.append(
        CreateFlowElem('121304377#0', 'flow_1', '900', '1200', '2100', 'human',
                       '29.5'))
    flows.append(
        CreateFlowElem('121304377#0', 'flow_2', '1200', '1500', '2016',
                       'human', '28.3'))
    flows.append(
        CreateFlowElem('121304377#0', 'flow_3', '1500', '1800', '2100',
                       'human', '27.1'))
    flows.append(
        CreateFlowElem('121304377#0', 'flow_4', '1800', '2100', '2212',
                       'human', '21.5'))
    flows.append(
        CreateFlowElem('121304377#0', 'flow_5', '2100', '2400', '2156',
                       'human', '8.3'))
    flows.append(
        CreateFlowElem('121304377#0', 'flow_6', '2400', '2700', '3360',
                       'human', '14.1'))
    flows.append(
        CreateFlowElem('121304377#0', 'flow_7', '2700', '3000', '2548',
                       'human', '16.9'))
    flows.append(
        CreateFlowElem('121304377#0', 'flow_8', '3000', '3300', '2324',
                       'human', '8.3'))
    flows.append(
        CreateFlowElem('121304377#0', 'flow_9', '3300', '3600', '2716',
                       'human', '9.1'))
    flows.append(
        CreateFlowElem('121304377#0', 'flow_10', '3600', '3900', '2548',
                       'human', '10.2'))
    flows.append(
        CreateFlowElem('121304377#0', 'flow_11', '3900', '4200', '2716',
                       'human', '9.3'))

    printxml(flows, filepath)
Exemple #7
0
    def make_routes(self, scenario, initial_config):

        type_list = scenario.vehicles.types
        num_cars = scenario.vehicles.num_vehicles
        if num_cars > 0:
            routes = makexml("routes", "http://sumo.dlr.de/xsd/routes_file.xsd")

            for veh_type in scenario.vehicles.types:
                routes.append(E("vType", id=veh_type, minGap="0"))

            vehicle_ids = scenario.vehicles.get_ids()

            if initial_config.shuffle:
                random.shuffle(vehicle_ids)

            positions = initial_config.positions
            ring_positions = positions[:scenario.vehicles.num_vehicles -
                                       scenario.num_merge_vehicles]
            merge_positions = positions[scenario.vehicles.num_vehicles -
                                        scenario.num_merge_vehicles:]
            i_merge = 0
            i_ring = 0
            for i, id in enumerate(vehicle_ids):
                if "merge" in scenario.vehicles.get_state(id, "type"):
                    route, pos = merge_positions[i_merge]
                    i_merge += 1
                else:
                    route, pos = ring_positions[i_ring]
                    i_ring += 1

                veh_type = scenario.vehicles.get_state(id, "type")
                type_depart_speed = scenario.vehicles.get_initial_speed(id)
                routes.append(
                    self._vehicle(veh_type, "route" + route,
                                  depart="0",
                                  departSpeed=str(type_depart_speed),
                                  departPos=str(pos), id=id, color="1,0.0,0.0")
                )

            printxml(routes, self.cfg_path + self.roufn)
Exemple #8
0
    def generate_cfg(self, net_params, traffic_lights, routes):
        """Generate .sumo.cfg files using net files and netconvert.

        This method is responsible for creating the following config files:

        - *.add.xml: This file contains the sumo-specific properties of
          vehicles with similar types, and properties of the traffic lights.
        - *.rou.xml: This file contains the routes vehicles can traverse,
          either from a specific starting edge, or by vehicle name, and well as
          the inflows of vehicles.
        - *.gui.cfg: This file contains the view settings of the gui (whether
          the gui is used or not). The background of the gui is set here to be
          grey, with RGB values: (100, 100, 100).
        - *.sumo.cfg: This is the file that is used by the simulator to
          identify the location of the various network, vehicle, and traffic
          light properties that are used when instantiating the simulation.

        Parameters
        ----------
        net_params : flow.core.params.NetParams
            see flow/core/params.py
        traffic_lights : flow.core.params.TrafficLightParams
            traffic light information, used to determine which nodes are
            treated as traffic lights
        routes : dict
            Key = name of the starting edge
            Element = list of edges a vehicle starting from this edge must
            traverse.
        """
        # this is the data that we will pass to the *.add.xml file
        add = makexml('additional',
                      'http://sumo.dlr.de/xsd/additional_file.xsd')

        # add the types of vehicles to the xml file
        for params in self.network.vehicles.types:
            type_params_str = {
                key: str(params['type_params'][key])
                for key in params['type_params']
            }
            add.append(E('vType', id=params['veh_id'], **type_params_str))

        # add (optionally) the traffic light properties to the .add.xml file
        num_traffic_lights = len(list(traffic_lights.get_properties().keys()))
        if num_traffic_lights > 0:
            if traffic_lights.baseline:
                tl_params = traffic_lights.actuated_default()
                tl_type = str(tl_params['tl_type'])
                program_id = str(tl_params['program_id'])
                phases = tl_params['phases']
                max_gap = str(tl_params['max_gap'])
                detector_gap = str(tl_params['detector_gap'])
                show_detector = tl_params['show_detectors']

                detectors = {'key': 'detector-gap', 'value': detector_gap}
                gap = {'key': 'max-gap', 'value': max_gap}

                if show_detector:
                    show_detector = {'key': 'show-detectors', 'value': 'true'}
                else:
                    show_detector = {'key': 'show-detectors', 'value': 'false'}

                nodes = self._inner_nodes  # nodes where there's traffic lights
                tll = []
                for node in nodes:
                    tll.append({
                        'id': node['id'],
                        'type': tl_type,
                        'programID': program_id
                    })

                for elem in tll:
                    e = E('tlLogic', **elem)
                    e.append(E('param', **show_detector))
                    e.append(E('param', **gap))
                    e.append(E('param', **detectors))
                    for phase in phases:
                        e.append(E('phase', **phase))
                    add.append(e)

            else:
                tl_properties = traffic_lights.get_properties()
                for node in tl_properties.values():
                    # At this point, we assume that traffic lights are properly
                    # formed. If there are no phases for a static traffic
                    # light, ignore and use default
                    if node['type'] == 'static' and not node.get('phases'):
                        continue

                    elem = {
                        'id': str(node['id']),
                        'type': str(node['type']),
                        'programID': str(node['programID'])
                    }
                    if node.get('offset'):
                        elem['offset'] = str(node.get('offset'))

                    e = E('tlLogic', **elem)
                    for key, value in node.items():
                        if key == 'phases':
                            for phase in node.get('phases'):
                                e.append(E('phase', **phase))
                        else:
                            e.append(
                                E('param', **{
                                    'key': key,
                                    'value': str(value)
                                }))

                    add.append(e)

        printxml(add, self.cfg_path + self.addfn)

        # this is the data that we will pass to the *.gui.cfg file
        gui = E('viewsettings')
        gui.append(E('scheme', name='real world'))
        gui.append(
            E('background',
              backgroundColor='100,100,100',
              showGrid='0',
              gridXSize='100.00',
              gridYSize='100.00'))
        printxml(gui, self.cfg_path + self.guifn)

        # this is the data that we will pass to the *.rou.xml file
        routes_data = makexml('routes',
                              'http://sumo.dlr.de/xsd/routes_file.xsd')

        # add the routes to the .add.xml file
        for route_id in routes.keys():
            # in this case, we only have one route, convert into into a
            # list of routes with one element
            if isinstance(routes[route_id][0], str):
                routes[route_id] = [(routes[route_id], 1)]

            # add each route incrementally, and add a second term to denote
            # the route number of the given route at the given edge
            for i in range(len(routes[route_id])):
                r, _ = routes[route_id][i]
                routes_data.append(
                    E('route',
                      id='route{}_{}'.format(route_id, i),
                      edges=' '.join(r)))

        # add the inflows from various edges to the xml file
        if self.network.net_params.inflows is not None:
            total_inflows = self.network.net_params.inflows.get()
            for inflow in total_inflows:
                # do not want to affect the original values
                sumo_inflow = deepcopy(inflow)

                # convert any non-string element in the inflow dict to a string
                for key in sumo_inflow:
                    if not isinstance(sumo_inflow[key], str):
                        sumo_inflow[key] = repr(sumo_inflow[key])

                # distribute the inflow rates across all routes from a given
                # edge on the basis of the provided fractions for each route
                edge = sumo_inflow['edge']
                del sumo_inflow['edge']

                for i, (_, frac) in enumerate(routes[edge]):
                    sumo_inflow['name'] += str(i)
                    sumo_inflow['route'] = 'route{}_{}'.format(edge, i)

                    for key in ['vehsPerHour', 'probability', 'period']:
                        if key in sumo_inflow:
                            sumo_inflow[key] = str(float(inflow[key]) * frac)

                    if 'number' in sumo_inflow:
                        sumo_inflow['number'] = str(
                            int(float(inflow['number']) * frac))

                    routes_data.append(_flow(**sumo_inflow))

        printxml(routes_data, self.cfg_path + self.roufn)

        # this is the data that we will pass to the *.sumo.cfg file
        cfg = makexml('configuration',
                      'http://sumo.dlr.de/xsd/sumoConfiguration.xsd')

        cfg.append(
            _inputs(net=self.netfn,
                    add=self.addfn,
                    rou=self.roufn,
                    gui=self.guifn))
        t = E('time')
        t.append(E('begin', value=repr(0)))
        cfg.append(t)

        printxml(cfg, self.cfg_path + self.sumfn)
        return self.sumfn
Exemple #9
0
    def generate_net(self,
                     net_params,
                     traffic_lights,
                     nodes,
                     edges,
                     types=None,
                     connections=None):
        """Generate Net files for the transportation network.

        Creates different network configuration files for:

        * nodes: x,y position of points which are connected together to form
          links. The nodes may also be fitted with traffic lights, or can be
          treated as priority or zipper merge regions if they combines several
          lanes or edges together.
        * edges: directed edges combining nodes together. These constitute the
          lanes vehicles will be allowed to drive on.
        * types (optional): parameters used to describe common features amount
          several edges of similar types. If edges are not defined with common
          types, this is not needed.
        * connections (optional): describes how incoming and outgoing edge/lane
          pairs on a specific node as connected. If none is specified, SUMO
          handles these connections by default.

        The above files are then combined to form a .net.xml file describing
        the shape of the traffic network in a form compatible with SUMO.

        Parameters
        ----------
        net_params : flow.core.params.NetParams
            network-specific parameters. Different networks require different
            net_params; see the separate sub-classes for more information.
        traffic_lights : flow.core.params.TrafficLightParams
            traffic light information, used to determine which nodes are
            treated as traffic lights
        nodes : list of dict
            A list of node attributes (a separate dict for each node). Nodes
            attributes must include:

            * id {string} -- name of the node
            * x {float} -- x coordinate of the node
            * y {float} -- y coordinate of the node

        edges : list of dict
            A list of edges attributes (a separate dict for each edge). Edge
            attributes must include:

            * id {string} -- name of the edge
            * from {string} -- name of node the directed edge starts from
            * to {string} -- name of the node the directed edge ends at

            In addition, the attributes must contain at least one of the
            following:

            * "numLanes" {int} and "speed" {float} -- the number of lanes and
              speed limit of the edge, respectively
            * type {string} -- a type identifier for the edge, which can be
              used if several edges are supposed to possess the same number of
              lanes, speed limits, etc...

        types : list of dict
            A list of type attributes for specific groups of edges. If none are
            specified, no .typ.xml file is created.
        connections : list of dict
            A list of connection attributes. If none are specified, no .con.xml
            file is created.

        Returns
        -------
        edges : dict <dict>
            Key = name of the edge
            Elements = length, lanes, speed
        connection_data : dict < dict < list < (edge, pos) > > >
            Key = name of the arriving edge
                Key = lane index
                Element = list of edge/lane pairs that a vehicle can traverse
                from the arriving edge/lane pairs
        """
        # add traffic lights to the nodes
        tl_ids = list(traffic_lights.get_properties().keys())
        for n_id in tl_ids:
            indx = next(i for i, nd in enumerate(nodes) if nd['id'] == n_id)
            nodes[indx]['type'] = 'traffic_light'

        # for nodes that have traffic lights that haven't been added
        for node in nodes:
            if node['id'] not in tl_ids \
                    and node.get('type', None) == 'traffic_light':
                traffic_lights.add(node['id'])

            # modify the x and y values to be strings
            node['x'] = str(node['x'])
            node['y'] = str(node['y'])
            if 'radius' in node:
                node['radius'] = str(node['radius'])

        # xml file for nodes; contains nodes for the boundary points with
        # respect to the x and y axes
        x = makexml('nodes', 'http://sumo.dlr.de/xsd/nodes_file.xsd')
        for node_attributes in nodes:
            x.append(E('node', **node_attributes))
        printxml(x, self.net_path + self.nodfn)

        # modify the length, shape, numLanes, and speed values
        for edge in edges:
            edge['length'] = str(edge['length'])
            if 'priority' in edge:
                edge['priority'] = str(edge['priority'])
            if 'shape' in edge:
                if not isinstance(edge['shape'], str):
                    edge['shape'] = ' '.join('%.2f,%.2f' % (x, y)
                                             for x, y in edge['shape'])
            if 'numLanes' in edge:
                edge['numLanes'] = str(edge['numLanes'])
            if 'speed' in edge:
                edge['speed'] = str(edge['speed'])

        # xml file for edges
        x = makexml('edges', 'http://sumo.dlr.de/xsd/edges_file.xsd')
        for edge_attributes in edges:
            x.append(E('edge', attrib=edge_attributes))
        printxml(x, self.net_path + self.edgfn)

        # xml file for types: contains the the number of lanes and the speed
        # limit for the lanes
        if types is not None:
            # modify the numLanes and speed values
            for typ in types:
                if 'numLanes' in typ:
                    typ['numLanes'] = str(typ['numLanes'])
                if 'speed' in typ:
                    typ['speed'] = str(typ['speed'])

            x = makexml('types', 'http://sumo.dlr.de/xsd/types_file.xsd')
            for type_attributes in types:
                x.append(E('type', **type_attributes))
            printxml(x, self.net_path + self.typfn)

        # xml for connections: specifies which lanes connect to which in the
        # edges
        if connections is not None:
            # modify the fromLane and toLane values
            for connection in connections:
                if 'fromLane' in connection:
                    connection['fromLane'] = str(connection['fromLane'])
                if 'toLane' in connection:
                    connection['toLane'] = str(connection['toLane'])

            x = makexml('connections',
                        'http://sumo.dlr.de/xsd/connections_file.xsd')
            for connection_attributes in connections:
                if 'signal_group' in connection_attributes:
                    del connection_attributes['signal_group']
                x.append(E('connection', **connection_attributes))
            printxml(x, self.net_path + self.confn)

        # xml file for configuration, which specifies:
        # - the location of all files of interest for sumo
        # - output net file
        # - processing parameters for no internal links and no turnarounds
        x = makexml('configuration',
                    'http://sumo.dlr.de/xsd/netconvertConfiguration.xsd')
        t = E('input')
        t.append(E('node-files', value=self.nodfn))
        t.append(E('edge-files', value=self.edgfn))
        if types is not None:
            t.append(E('type-files', value=self.typfn))
        if connections is not None:
            t.append(E('connection-files', value=self.confn))
        x.append(t)
        t = E('output')
        t.append(E('output-file', value=self.netfn))
        x.append(t)
        t = E('processing')
        t.append(E('no-internal-links', value='false'))
        t.append(E('no-turnarounds', value='true'))
        x.append(t)
        printxml(x, self.net_path + self.cfgfn)

        subprocess.call([
            'netconvert -c ' + self.net_path + self.cfgfn + ' --output-file=' +
            self.cfg_path + self.netfn + ' --no-internal-links="false"'
        ],
                        shell=True)

        # collect data from the generated network configuration file
        error = None
        for _ in range(RETRIES_ON_ERROR):
            try:
                edges_dict, conn_dict = self._import_edges_from_net(net_params)
                return edges_dict, conn_dict
            except Exception as e:
                print('Error during start: {}'.format(e))
                print('Retrying in {} seconds...'.format(WAIT_ON_ERROR))
                time.sleep(WAIT_ON_ERROR)
        raise error
Exemple #10
0
    def generate_cfg(self, net_params, traffic_lights, routes):
        """Generate .sumo.cfg files using net files and netconvert.

        This includes files such as the routes vehicles can traverse,
        properties of the traffic lights, and the view settings of the gui
        (whether the gui is used or not). The background of the gui is set here
        to be grey, with RGB values: (100, 100, 100).

        Parameters
        ----------
        net_params : NetParams type
            see flow/core/params.py
        traffic_lights : flow.core.traffic_lights.TrafficLights type
            traffic light information, used to determine which nodes are
            treated as traffic lights
        routes : dict
            Key = name of the starting edge
            Element = list of edges a vehicle starting from this edge must
            traverse.
        """
        # specify routes vehicles can take
        self.rts = routes

        add = makexml('additional',
                      'http://sumo.dlr.de/xsd/additional_file.xsd')

        # add the routes to the .add.xml file
        for (edge, route) in self.rts.items():
            add.append(E('route', id='route%s' % edge, edges=' '.join(route)))

        # add (optionally) the traffic light properties to the .add.xml file
        num_traffic_lights = len(list(traffic_lights.get_properties().keys()))
        if num_traffic_lights > 0:
            if traffic_lights.baseline:
                tl_params = traffic_lights.actuated_default()
                tl_type = str(tl_params['tl_type'])
                program_id = str(tl_params['program_id'])
                phases = tl_params['phases']
                max_gap = str(tl_params['max_gap'])
                detector_gap = str(tl_params['detector_gap'])
                show_detector = tl_params['show_detectors']

                detectors = {'key': 'detector-gap', 'value': detector_gap}
                gap = {'key': 'max-gap', 'value': max_gap}

                if show_detector:
                    show_detector = {'key': 'show-detectors', 'value': 'true'}
                else:
                    show_detector = {'key': 'show-detectors', 'value': 'false'}

                # FIXME(ak): add abstract method
                nodes = self.specify_tll(net_params)
                tll = []
                for node in nodes:
                    tll.append({
                        'id': node['id'],
                        'type': tl_type,
                        'programID': program_id
                    })

                for elem in tll:
                    e = E('tlLogic', **elem)
                    e.append(E('param', **show_detector))
                    e.append(E('param', **gap))
                    e.append(E('param', **detectors))
                    for phase in phases:
                        e.append(E('phase', **phase))
                    add.append(e)

            else:
                tl_properties = traffic_lights.get_properties()
                for node in tl_properties.values():
                    # At this point, we assume that traffic lights are properly
                    # formed. If there are no phases for a static traffic
                    # light, ignore and use default
                    if node['type'] == 'static' and not node.get('phases'):
                        continue

                    elem = {
                        'id': str(node['id']),
                        'type': str(node['type']),
                        'programID': str(node['programID'])
                    }
                    if node.get('offset'):
                        elem['offset'] = str(node.get('offset'))

                    e = E('tlLogic', **elem)
                    for key, value in node.items():
                        if key == 'phases':
                            for phase in node.get('phases'):
                                e.append(E('phase', **phase))
                        else:
                            e.append(
                                E('param', **{
                                    'key': key,
                                    'value': str(value)
                                }))

                    add.append(e)

        printxml(add, self.cfg_path + self.addfn)

        gui = E('viewsettings')
        gui.append(E('scheme', name='real world'))
        gui.append(
            E('background',
              backgroundColor='100,100,100',
              showGrid='0',
              gridXSize='100.00',
              gridYSize='100.00'))
        printxml(gui, self.cfg_path + self.guifn)

        cfg = makexml('configuration',
                      'http://sumo.dlr.de/xsd/sumoConfiguration.xsd')

        cfg.append(
            _inputs(net=self.netfn,
                    add=self.addfn,
                    rou=self.roufn,
                    gui=self.guifn))
        t = E('time')
        t.append(E('begin', value=repr(0)))
        cfg.append(t)

        printxml(cfg, self.cfg_path + self.sumfn)
        return self.sumfn
Exemple #11
0
    def generate_net(self, net_params, traffic_lights):
        """Generates Net files for the transportation network.

        Creates different network configuration files for:

        * nodes: x,y position of points which are connected together to form
          links. The nodes may also be fitted with traffic lights, or can be
          treated as priority or zipper merge regions if they combines several
          lanes or edges together.
        * edges: directed edges combining nodes together. These constitute the
          lanes vehicles will be allowed to drive on.
        * types (optional): parameters used to describe common features amount
          several edges of similar types. If edges are not defined with common
          types, this is not needed.
        * connections (optional): describes how incoming and outgoing edge/lane
          pairs on a specific node as connected. If none is specified, SUMO
          handles these connections by default.

        The above files are then combined to form a .net.xml file describing
        the shape of the traffic network in a form compatible with SUMO.

        Parameters
        ----------
        net_params : flow.core.params.NetParams type
            network-specific parameters. Different networks require different
            net_params; see the separate sub-classes for more information.
        traffic_lights : flow.core.traffic_lights.TrafficLights type
            traffic light information, used to determine which nodes are
            treated as traffic lights

        Returns
        -------
        edges : dict <dict>
            Key = name of the edge
            Elements = length, lanes, speed
        connection_data : dict < dict < list<tup> > >
            Key = name of the arriving edge
                Key = lane index
                Element = list of edge/lane pairs that a vehicle can traverse
                from the arriving edge/lane pairs

        """
        nodfn = "%s.nod.xml" % self.name
        edgfn = "%s.edg.xml" % self.name
        typfn = "%s.typ.xml" % self.name
        cfgfn = "%s.netccfg" % self.name
        netfn = "%s.net.xml" % self.name
        confn = "%s.con.xml" % self.name
        # specify the attributes of the nodes
        nodes = self.specify_nodes(net_params)

        # add traffic lights to the nodes
        for n_id in traffic_lights.get_ids():
            indx = next(i for i, nd in enumerate(nodes) if nd["id"] == n_id)
            nodes[indx]["type"] = "traffic_light"

        # xml file for nodes; contains nodes for the boundary points with
        # respect to the x and y axes
        x = makexml("nodes", "http://sumo.dlr.de/xsd/nodes_file.xsd")
        for node_attributes in nodes:
            x.append(E("node", **node_attributes))
        printxml(x, self.net_path + nodfn)

        # collect the attributes of each edge
        edges = self.specify_edges(net_params)

        # xml file for edges
        x = makexml("edges", "http://sumo.dlr.de/xsd/edges_file.xsd")
        for edge_attributes in edges:
            x.append(E("edge", attrib=edge_attributes))
        printxml(x, self.net_path + edgfn)

        # specify the types attributes (default is None)
        types = self.specify_types(net_params)

        # xml file for types: contains the the number of lanes and the speed
        # limit for the lanes
        if types is not None:
            x = makexml("types", "http://sumo.dlr.de/xsd/types_file.xsd")
            for type_attributes in types:
                x.append(E("type", **type_attributes))
            printxml(x, self.net_path + typfn)

        # specify the connection attributes (default is None)
        connections = self.specify_connections(net_params)

        # xml for connections: specifies which lanes connect to which in the
        # edges
        if connections is not None:
            x = makexml("connections",
                        "http://sumo.dlr.de/xsd/connections_file.xsd")
            for connection_attributes in connections:
                x.append(E("connection", **connection_attributes))
            printxml(x, self.net_path + confn)

        # check whether the user requested no-internal-links (default="true")
        if net_params.no_internal_links:
            no_internal_links = "true"
        else:
            no_internal_links = "false"

        # xml file for configuration, which specifies:
        # - the location of all files of interest for sumo
        # - output net file
        # - processing parameters for no internal links and no turnarounds
        x = makexml("configuration",
                    "http://sumo.dlr.de/xsd/netconvertConfiguration.xsd")
        t = E("input")
        t.append(E("node-files", value=nodfn))
        t.append(E("edge-files", value=edgfn))
        if types is not None:
            t.append(E("type-files", value=typfn))
        if connections is not None:
            t.append(E("connection-files", value=confn))
        x.append(t)
        t = E("output")
        t.append(E("output-file", value=netfn))
        x.append(t)
        t = E("processing")
        t.append(E("no-internal-links", value="%s" % no_internal_links))
        t.append(E("no-turnarounds", value="true"))
        x.append(t)
        printxml(x, self.net_path + cfgfn)

        subprocess.call([
            "netconvert -c " + self.net_path + cfgfn + " --output-file=" +
            self.cfg_path + netfn +
            ' --no-internal-links="%s"' % no_internal_links
        ],
                        shell=True)

        # location of the .net.xml file
        self.netfn = netfn

        # collect data from the generated network configuration file
        error = None
        for _ in range(RETRIES_ON_ERROR):
            try:
                edges_dict, conn_dict = self._import_edges_from_net()
                return edges_dict, conn_dict
            except Exception as error:
                print("Error during start: {}".format(traceback.format_exc()))
                print("Retrying in {} seconds...".format(WAIT_ON_ERROR))
                time.sleep(WAIT_ON_ERROR)
        raise error
Exemple #12
0
    def generate_cfg(self, net_params, traffic_lights):
        """Generates .sumo.cfg files using net files and netconvert.

        This includes files such as the routes vehicles can traverse,
        properties of the traffic lights, and the view settings of the gui
        (whether the gui is used or not). The background of the gui is set here
        to be grey, with RGB values: (100, 100, 100).

        Parameters
        ----------
        net_params: NetParams type
            see flow/core/params.py
        traffic_lights : flow.core.traffic_lights.TrafficLights type
            traffic light information, used to determine which nodes are
            treated as traffic lights
        """
        start_time = 0
        end_time = None

        self.roufn = "%s.rou.xml" % self.name
        addfn = "%s.add.xml" % self.name
        cfgfn = "%s.sumo.cfg" % self.name
        guifn = "%s.gui.cfg" % self.name

        # specify routes vehicles can take
        self.rts = self.specify_routes(net_params)

        add = makexml("additional",
                      "http://sumo.dlr.de/xsd/additional_file.xsd")

        # add the routes to the .add.xml file
        for (edge, route) in self.rts.items():
            add.append(E("route", id="route%s" % edge, edges=" ".join(route)))

        # add (optionally) the traffic light properties to the .add.xml file
        if traffic_lights.num_traffic_lights > 0:
            if traffic_lights.baseline:
                tl_type = str(traffic_lights["tl_type"])
                program_id = str(traffic_lights["program_id"])
                phases = traffic_lights["phases"]
                max_gap = str(traffic_lights["max_gap"])
                detector_gap = str(traffic_lights["detector_gap"])
                show_detector = traffic_lights["show_detectors"]

                detectors = {"key": "detector-gap", "value": detector_gap}
                gap = {"key": "max-gap", "value": max_gap}

                if show_detector:
                    show_detector = {"key": "show-detectors", "value": "true"}
                else:
                    show_detector = {"key": "show-detectors", "value": "false"}

                # FIXME(ak): add abstract method
                nodes = self.specify_tll(net_params)
                tll = []
                for node in nodes:
                    tll.append({
                        "id": node['id'],
                        "type": tl_type,
                        "programID": program_id
                    })

                for elem in tll:
                    e = E("tlLogic", **elem)
                    e.append(E("param", **show_detector))
                    e.append(E("param", **gap))
                    e.append(E("param", **detectors))
                    for phase in phases:
                        e.append(E("phase", **phase))
                    add.append(e)

            else:
                tl_properties = traffic_lights.get_properties()
                for node in tl_properties.values():
                    # at this point, the generator assumes that traffic lights
                    # are properly formed. If there are no phases for a static
                    # traffic light, ignore and use default
                    if node["type"] == "static" and not node.get("phases"):
                        continue

                    elem = {
                        "id": str(node["id"]),
                        "type": str(node["type"]),
                        "programID": str(node["programID"])
                    }
                    if node.get("offset"):
                        elem["offset"] = str(node.get("offset"))

                    e = E("tlLogic", **elem)
                    for key, value in node.items():
                        if key == "phases":
                            for phase in node.get("phases"):
                                e.append(E("phase", **phase))
                        else:
                            e.append(
                                E("param", **{
                                    "key": key,
                                    "value": str(value)
                                }))

                    add.append(e)

        printxml(add, self.cfg_path + addfn)

        gui = E("viewsettings")
        gui.append(E("scheme", name="real world"))
        gui.append(
            E("background",
              backgroundColor="100,100,100",
              showGrid="0",
              gridXSize="100.00",
              gridYSize="100.00"))
        printxml(gui, self.cfg_path + guifn)

        cfg = makexml("configuration",
                      "http://sumo.dlr.de/xsd/sumoConfiguration.xsd")

        logging.debug(self.netfn)

        cfg.append(
            self._inputs(self.name,
                         net=self.netfn,
                         add=addfn,
                         rou=self.roufn,
                         gui=guifn))
        t = E("time")
        t.append(E("begin", value=repr(start_time)))
        if end_time:
            t.append(E("end", value=repr(end_time)))
        cfg.append(t)

        printxml(cfg, self.cfg_path + cfgfn)
        return cfgfn
Exemple #13
0
from lxml import etree
E = etree  #.Element
import xml.etree.ElementTree as ET
from flow.core.util import makexml, printxml, ensure_dir

file = "/home/mesto/flow/MyTests/I24-62.add.xml"
tree = E.parse(file)
if __name__ == "__main__":
    root = tree.getroot()
    #tree.append(file)
    add = makexml('additional', 'http://sumo.dlr.de/xsd/additional_file.xsd')
    for child in root:
        add.append(child)
    #add.append(E('flow', id = 'Test'))
    printxml(add, "/home/mesto/flow/MyTests/test.xml")
Exemple #14
0
    def make_routes(self, scenario, positions, lanes, shuffle):
        """Generates .rou.xml files using net files and netconvert.

        This file specifies the sumo-specific properties of vehicles with
        similar types, and well as the starting positions of vehicles. The
        starting positions, however, may be modified in real-time (e.g. during
        an environment reset).

        Parameters
        ----------
        scenario : Scenario type
            scenario class calling this method. This contains information on
            the properties and initial states of vehicles in the network.
        positions : list of tuple (float, float)
            list of start positions [(edge0, pos0), (edge1, pos1), ...]
        lanes : list of float
            list of start lanes
        shuffle : bool
            specifies whether the vehicle IDs should be shuffled before the
            vehicles are assigned starting positions
        """
        vehicles = scenario.vehicles
        routes = makexml("routes", "http://sumo.dlr.de/xsd/routes_file.xsd")

        # add the types of vehicles to the xml file
        for params in vehicles.types:
            type_params_str = {
                key: str(params["type_params"][key])
                for key in params["type_params"]
            }
            routes.append(E("vType", id=params["veh_id"], **type_params_str))

        self.vehicle_ids = vehicles.get_ids()

        if shuffle:
            random.shuffle(self.vehicle_ids)

        # add the initial positions of vehicles to the xml file
        for i, veh_id in enumerate(self.vehicle_ids):
            veh_type = vehicles.get_state(veh_id, "type")
            edge, pos = positions[i]
            lane = lanes[i]
            type_depart_speed = vehicles.get_initial_speed(veh_id)
            routes.append(
                self._vehicle(veh_type,
                              "route" + edge,
                              depart="0",
                              id=veh_id,
                              color="1,1,1",
                              departSpeed=str(type_depart_speed),
                              departPos=str(pos),
                              departLane=str(lane)))

        # add the in-flows from various edges to the xml file
        if self.net_params.in_flows is not None:
            total_inflows = self.net_params.in_flows.get()
            for inflow in total_inflows:
                for key in inflow:
                    if not isinstance(inflow[key], str):
                        inflow[key] = repr(inflow[key])
                routes.append(self._flow(**inflow))

        printxml(routes, self.cfg_path + self.roufn)
Exemple #15
0
    def generate_net(self, net_params):
        """
        Generates Net files for the transportation network. Different networks
        require different net_params; see the separate sub-classes for more
        information.
        """
        nodfn = "%s.nod.xml" % self.name
        edgfn = "%s.edg.xml" % self.name
        typfn = "%s.typ.xml" % self.name
        cfgfn = "%s.netccfg" % self.name
        netfn = "%s.net.xml" % self.name
        confn = "%s.con.xml" % self.name

        # specify the attributes of the nodes
        nodes = self.specify_nodes(net_params)

        # xml file for nodes; contains nodes for the boundary points with
        # respect to the x and y axes
        x = makexml("nodes", "http://sumo.dlr.de/xsd/nodes_file.xsd")
        for node_attributes in nodes:
            x.append(E("node", **node_attributes))
        printxml(x, self.net_path + nodfn)

        # collect the attributes of each edge
        edges = self.specify_edges(net_params)

        # xml file for edges
        x = makexml("edges", "http://sumo.dlr.de/xsd/edges_file.xsd")
        for edge_attributes in edges:
            x.append(E("edge", attrib=edge_attributes))
        printxml(x, self.net_path + edgfn)

        # specify the types attributes (default is None)
        types = self.specify_types(net_params)

        # xml file for types: contains the the number of lanes and the speed
        # limit for the lanes
        if types is not None:
            x = makexml("types", "http://sumo.dlr.de/xsd/types_file.xsd")
            for type_attributes in types:
                x.append(E("type", **type_attributes))
            printxml(x, self.net_path + typfn)

        # specify the connection attributes (default is None)
        connections = self.specify_connections(net_params)

        # xml for connections: specifies which lanes connect to which in the
        # edges
        if connections is not None:
            x = makexml("connections",
                        "http://sumo.dlr.de/xsd/connections_file.xsd")
            for connection_attributes in connections:
                x.append(E("connection", **connection_attributes))
            printxml(x, self.net_path + confn)

        # check whether the user requested no-internal-links (default="true")
        if net_params.no_internal_links:
            no_internal_links = "true"
        else:
            no_internal_links = "false"

        # xml file for configuration, which specifies:
        # - the location of all files of interest for sumo
        # - output net file
        # - processing parameters for no internal links and no turnarounds
        x = makexml("configuration",
                    "http://sumo.dlr.de/xsd/netconvertConfiguration.xsd")
        t = E("input")
        t.append(E("node-files", value=nodfn))
        t.append(E("edge-files", value=edgfn))
        if types is not None:
            t.append(E("type-files", value=typfn))
        if connections is not None:
            t.append(E("connection-files", value=confn))
        x.append(t)
        t = E("output")
        t.append(E("output-file", value=netfn))
        x.append(t)
        t = E("processing")
        t.append(E("no-internal-links", value="%s" % no_internal_links))
        t.append(E("no-turnarounds", value="true"))
        x.append(t)
        printxml(x, self.net_path + cfgfn)

        retcode = subprocess.call(
            ["netconvert -c " + self.net_path + cfgfn + " --output-file=" +
             self.cfg_path + netfn + ' --no-internal-links="%s"'
             % no_internal_links],
            stdout=sys.stdout, stderr=sys.stderr, shell=True)

        self.netfn = netfn

        return self.net_path + netfn