2018-10-23 01:29:21 +08:00
|
|
|
#!/usr/bin/env python
|
|
|
|
|
2019-03-29 17:58:05 +08:00
|
|
|
# Copyright (c) 2019 Computer Vision Center (CVC) at the Universitat Autonoma de
|
2018-10-28 18:23:59 +08:00
|
|
|
# Barcelona (UAB).
|
|
|
|
#
|
|
|
|
# This work is licensed under the terms of the MIT license.
|
|
|
|
# For a copy, see <https://opensource.org/licenses/MIT>.
|
|
|
|
|
|
|
|
"""
|
|
|
|
CARLA Dynamic Weather:
|
|
|
|
|
|
|
|
Connect to a CARLA Simulator instance and control the weather. Change Sun
|
|
|
|
position smoothly with time and generate storms occasionally.
|
|
|
|
"""
|
|
|
|
|
2018-10-23 01:29:21 +08:00
|
|
|
import glob
|
|
|
|
import os
|
|
|
|
import sys
|
|
|
|
|
|
|
|
try:
|
2019-03-29 02:15:13 +08:00
|
|
|
sys.path.append(glob.glob('../carla/dist/carla-*%d.%d-%s.egg' % (
|
2018-10-23 01:29:21 +08:00
|
|
|
sys.version_info.major,
|
|
|
|
sys.version_info.minor,
|
|
|
|
'win-amd64' if os.name == 'nt' else 'linux-x86_64'))[0])
|
|
|
|
except IndexError:
|
|
|
|
pass
|
|
|
|
|
|
|
|
import carla
|
|
|
|
|
|
|
|
import argparse
|
|
|
|
import math
|
|
|
|
|
|
|
|
|
|
|
|
def clamp(value, minimum=0.0, maximum=100.0):
|
|
|
|
return max(minimum, min(value, maximum))
|
|
|
|
|
|
|
|
|
|
|
|
class Sun(object):
|
|
|
|
def __init__(self, azimuth, altitude):
|
|
|
|
self.azimuth = azimuth
|
|
|
|
self.altitude = altitude
|
|
|
|
self._t = 0.0
|
|
|
|
|
|
|
|
def tick(self, delta_seconds):
|
|
|
|
self._t += 0.008 * delta_seconds
|
|
|
|
self._t %= 2.0 * math.pi
|
|
|
|
self.azimuth += 0.25 * delta_seconds
|
|
|
|
self.azimuth %= 360.0
|
|
|
|
self.altitude = 35.0 * (math.sin(self._t) + 1.0)
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
return 'Sun(%.2f, %.2f)' % (self.azimuth, self.altitude)
|
|
|
|
|
|
|
|
|
|
|
|
class Storm(object):
|
|
|
|
def __init__(self, precipitation):
|
|
|
|
self._t = precipitation if precipitation > 0.0 else -50.0
|
|
|
|
self._increasing = True
|
|
|
|
self.clouds = 0.0
|
|
|
|
self.rain = 0.0
|
|
|
|
self.puddles = 0.0
|
|
|
|
self.wind = 0.0
|
|
|
|
|
|
|
|
def tick(self, delta_seconds):
|
|
|
|
delta = (1.3 if self._increasing else -1.3) * delta_seconds
|
|
|
|
self._t = clamp(delta + self._t, -250.0, 100.0)
|
|
|
|
self.clouds = clamp(self._t + 40.0, 0.0, 90.0)
|
|
|
|
self.rain = clamp(self._t, 0.0, 80.0)
|
|
|
|
delay = -10.0 if self._increasing else 90.0
|
|
|
|
self.puddles = clamp(self._t + delay, 0.0, 75.0)
|
|
|
|
self.wind = clamp(self._t - delay, 0.0, 80.0)
|
|
|
|
if self._t == -250.0:
|
|
|
|
self._increasing = True
|
|
|
|
if self._t == 100.0:
|
|
|
|
self._increasing = False
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
return 'Storm(clouds=%d%%, rain=%d%%, wind=%d%%)' % (self.clouds, self.rain, self.wind)
|
|
|
|
|
|
|
|
|
|
|
|
class Weather(object):
|
|
|
|
def __init__(self, weather):
|
|
|
|
self.weather = weather
|
|
|
|
self._sun = Sun(weather.sun_azimuth_angle, weather.sun_altitude_angle)
|
|
|
|
self._storm = Storm(weather.precipitation)
|
|
|
|
|
|
|
|
def tick(self, delta_seconds):
|
|
|
|
self._sun.tick(delta_seconds)
|
|
|
|
self._storm.tick(delta_seconds)
|
|
|
|
self.weather.cloudyness = self._storm.clouds
|
|
|
|
self.weather.precipitation = self._storm.rain
|
|
|
|
self.weather.precipitation_deposits = self._storm.puddles
|
|
|
|
self.weather.wind_intensity = self._storm.wind
|
|
|
|
self.weather.sun_azimuth_angle = self._sun.azimuth
|
|
|
|
self.weather.sun_altitude_angle = self._sun.altitude
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
return '%s %s' % (self._sun, self._storm)
|
|
|
|
|
|
|
|
|
|
|
|
def main():
|
|
|
|
argparser = argparse.ArgumentParser(
|
2018-10-28 18:23:59 +08:00
|
|
|
description=__doc__)
|
2018-10-23 01:29:21 +08:00
|
|
|
argparser.add_argument(
|
|
|
|
'--host',
|
|
|
|
metavar='H',
|
|
|
|
default='127.0.0.1',
|
|
|
|
help='IP of the host server (default: 127.0.0.1)')
|
|
|
|
argparser.add_argument(
|
|
|
|
'-p', '--port',
|
|
|
|
metavar='P',
|
|
|
|
default=2000,
|
|
|
|
type=int,
|
|
|
|
help='TCP port to listen to (default: 2000)')
|
|
|
|
argparser.add_argument(
|
|
|
|
'-s', '--speed',
|
|
|
|
metavar='FACTOR',
|
|
|
|
default=1.0,
|
|
|
|
type=float,
|
2018-10-28 18:23:59 +08:00
|
|
|
help='rate at which the weather changes (default: 1.0)')
|
2018-10-23 01:29:21 +08:00
|
|
|
args = argparser.parse_args()
|
|
|
|
|
|
|
|
speed_factor = args.speed
|
|
|
|
update_freq = 0.1 / speed_factor
|
|
|
|
|
|
|
|
client = carla.Client(args.host, args.port)
|
|
|
|
client.set_timeout(2.0)
|
|
|
|
world = client.get_world()
|
|
|
|
|
|
|
|
weather = Weather(world.get_weather())
|
|
|
|
|
|
|
|
elapsed_time = 0.0
|
|
|
|
|
|
|
|
while True:
|
2019-06-18 00:33:40 +08:00
|
|
|
timestamp = world.wait_for_tick(seconds=30.0).timestamp
|
2018-10-23 01:29:21 +08:00
|
|
|
elapsed_time += timestamp.delta_seconds
|
|
|
|
if elapsed_time > update_freq:
|
|
|
|
weather.tick(speed_factor * elapsed_time)
|
|
|
|
world.set_weather(weather.weather)
|
|
|
|
sys.stdout.write('\r' + str(weather) + 12 * ' ')
|
|
|
|
sys.stdout.flush()
|
|
|
|
elapsed_time = 0.0
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
|
|
|
|
main()
|