Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

分布式Carla Server代码整理 #30

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
201 changes: 201 additions & 0 deletions multicarlaservers/Mult-carla/carlaSimulation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
# ==================================================================================================
# -- imports ---------------------------------------------------------------------------------------
# ==================================================================================================

import logging

import carla # pylint: disable=import-error

# from .constants import INVALID_ACTOR_ID

# ==================================================================================================
# -- carla simulation ------------------------------------------------------------------------------
# ==================================================================================================


class CarlaSimulation(object):
"""
CarlaSimulation is responsible for the management of the carla simulation.
"""
def __init__(self, host, port, step_length,server_id):
self.id = server_id
try:
self.client = carla.Client(host, port)
except Exception as error:
raise error
self.client.set_timeout(2.0)

self.world = self.client.get_world()
self.blueprint_library = self.world.get_blueprint_library()
self.step_length = step_length
self.isSumo = False

# 记录,是本机生成的actor还是外机同步的actor
self.ontology = set()
self.avatars = {} # { carla_id : set( (id_inworld,id_onworld) )}

self.actors = None

# Set traffic lights.
self._tls = {} # {landmark_id: traffic_ligth_actor}

tmp_map = self.world.get_map()
self.map_hash = hash(tmp_map.to_opendrive())
for landmark in tmp_map.get_all_landmarks_of_type('1000001'):
if landmark.id != '':
traffic_light = self.world.get_traffic_light(landmark)
if traffic_light is not None:
self._tls[landmark.id] = traffic_light
else:
logging.warning('Landmark %s is not linked to any traffic light', landmark.id)

def update_info(self):
"""
For getting new information.
"""
self.actors = None

def get_actor(self, actor_id):
"""
Accessor for carla actor.
"""
if not self.actors:
self.actors =self.get_actors()

return self.actors.find(actor_id)

def get_actors(self,actor_ids=None):
"""
Accessor for carla actors.
"""
if actor_ids:
self.actors = self.world.get_actors(actor_ids)
else:
self.actors = self.world.get_actors()
return self.actors

# This is a workaround to fix synchronization issues when other carla clients remove an actor in
# carla without waiting for tick (e.g., running sumo co-simulation and manual control at the
# same time)
def get_actor_light_state(self, actor_id):
"""
Accessor for carla actor light state.

If the actor is not alive, returns None.
"""
try:
actor = self.get_actor(actor_id)
return actor.get_light_state()
except RuntimeError:
return None

@property
def traffic_light_ids(self):
return set(self._tls.keys())

def get_traffic_light_state(self, landmark_id):
"""
Accessor for traffic light state.

If the traffic ligth does not exist, returns None.
"""
if landmark_id not in self._tls:
return None
return self._tls[landmark_id].state

def switch_off_traffic_lights(self):
"""
Switch off all traffic lights.
"""
for actor in self.world.get_actors():
if actor.type_id == 'traffic.traffic_light':
actor.freeze(True)
# We set the traffic light to 'green' because 'off' state sets the traffic light to
# 'red'.
actor.set_state(carla.TrafficLightState.Green)

def spawn_actor(self, blueprint, transform):
"""
Spawns a new actor.
:param blueprint: blueprint of the actor to be spawned.
:param transform: transform where the actor will be spawned.
:return: actor id if the actor is successfully spawned. Otherwise, INVALID_ACTOR_ID.
"""

batch = [
carla.command.SpawnActor(blueprint, transform).then(
carla.command.SetSimulatePhysics(carla.command.FutureActor, False))
]
response = self.client.apply_batch_sync(batch, False)[0]
if response.error:
logging.error('Spawn carla actor failed. %s', response.error)
return -1
# return INVALID_ACTOR_ID

return response.actor_id

def destroy_actor(self, actor_id):
"""
Destroys the given actor.
"""
actor = self.world.get_actor(actor_id)
if actor is not None:
return actor.destroy()
return False

def synchronize_vehicle(self, vehicle_id, transform, lights=None):
"""
Updates vehicle state.

:param vehicle_id: id of the actor to be updated.
:param transform: new vehicle transform (i.e., position and rotation).
:param lights: new vehicle light state.
:return: True if successfully updated. Otherwise, False.
"""
vehicle = self.world.get_actor(vehicle_id)
if vehicle is None:
return False

vehicle.set_transform(transform)
if lights is not None:
vehicle.set_light_state(carla.VehicleLightState(lights))
return True

def synchronize_traffic_light(self, landmark_id, state):
"""
Updates traffic light state.

:param landmark_id: id of the landmark to be updated.
:param state: new traffic light state.
:return: True if successfully updated. Otherwise, False.
"""
if not landmark_id in self._tls:
logging.warning('Landmark %s not found in carla', landmark_id)
return False

traffic_light = self._tls[landmark_id]
traffic_light.set_state(state)
return True

def tick(self):
"""
Tick to carla simulation.
"""
self.world.tick()

"""
# Update data structures for the current frame.
current_actors = set(
[vehicle.id for vehicle in self.world.get_actors().filter('vehicle.*')])
self.spawned_actors = current_actors.difference(self._active_actors)
self.destroyed_actors = self._active_actors.difference(current_actors)
self._active_actors = current_actors

"""
def close(self):
"""
Closes carla client.
"""
for actor in self.world.get_actors():
if actor.type_id == 'traffic.traffic_light':
actor.freeze(False)
17 changes: 17 additions & 0 deletions multicarlaservers/Mult-carla/carlaservers.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
servers:
- host: 192.168.3.34
port: 2000
- host: 192.168.3.43
port: 2000
- host: 192.168.3.32
port: 2000

# sumo:
# - host: 192.168.3.34
# port: 2000

actorlights: false
actorcolor: false
trafficlights: false
weather: null
steplength: 0.05
Loading