def _initialize_traci_conn(self, num_retries=5):
        # TODO: inline sumo or process pool
        # the retries are to deal with port collisions
        #   since the way we start sumo here has a race condition on
        #   each spawned process claiming a port
        for _ in range(num_retries):
            self._close_traci_and_pipes()

            sumo_port = self._sumo_port
            if sumo_port is None:
                sumo_port = networking.find_free_port()

            sumo_binary = "sumo" if self._headless else "sumo-gui"
            sumo_cmd = [
                os.path.join(SUMO_PATH, "bin", sumo_binary),
                "--remote-port=%s" % sumo_port,
                *self._base_sumo_load_params(),
            ]

            self._log.debug("Starting sumo process:\n\t %s", sumo_cmd)
            self._sumo_proc = subprocess.Popen(
                sumo_cmd,
                stdin=subprocess.PIPE,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
                close_fds=True,
            )
            time.sleep(0.05)  # give SUMO time to start
            try:
                with surpress_stdout():
                    self._traci_conn = traci.connect(
                        sumo_port,
                        numRetries=100,
                        proc=self._sumo_proc,
                        waitBetweenRetries=0.05,
                    )  # SUMO must be ready within 5 seconds

                try:
                    assert (
                        self._traci_conn.getVersion()[0] >= 20
                    ), "TraCI API version must be >= 20 (SUMO 1.5.0)"
                # We will retry since this is our first sumo command
                except FatalTraCIError:
                    logging.debug("Connection closed. Retrying...")
                    self._close_traci_and_pipes()
                    continue
            except ConnectionRefusedError:
                logging.debug(
                    "Connection refused. Tried to connect to unpaired TraCI client."
                )
                self._close_traci_and_pipes()
                continue

            # It is mandatory to set order when using multiple clients.
            self._traci_conn.setOrder(0)

            break

        try:
            self._traci_conn.getVersion()
        except Exception as e:
            logging.error(
                f"""Failed to initialize SUMO
                Your scenario might not be configured correctly or
                you were trying to initialize many SUMO instances at
                once and we were not able to assign unique port
                numbers to all SUMO processes.

                Check {self._log_file} for hints"""
            )
            raise e

        self._log.debug("Finished starting sumo process")
Beispiel #2
0
# Copyright (C) 2020. Huawei Technologies Co., Ltd. All rights reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.

from smarts.core.utils.logging import surpress_stdout

# XXX: Importing pybullet logs an annoying build version tag. There's no "friendly"
#      way to fix this since they simply use print(...). Disabling logging at the
#      time of import is our hack.
with surpress_stdout():
    from pybullet import *
    from pybullet_utils import bullet_client