carla/PythonAPI/examples/spawn_npc.py

231 lines
8.4 KiB
Python
Raw Normal View History

2018-10-29 00:46:37 +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-29 00:46:37 +08:00
# Barcelona (UAB).
#
# This work is licensed under the terms of the MIT license.
# For a copy, see <https://opensource.org/licenses/MIT>.
"""Spawn NPCs into the simulation"""
import glob
import os
import sys
import time
2018-10-29 00:46:37 +08:00
try:
2019-03-29 02:15:13 +08:00
sys.path.append(glob.glob('../carla/dist/carla-*%d.%d-%s.egg' % (
2018-10-29 00:46:37 +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 logging
2018-10-29 00:46:37 +08:00
import random
def main():
argparser = argparse.ArgumentParser(
description=__doc__)
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(
2018-10-30 19:00:00 +08:00
'-n', '--number-of-vehicles',
2018-10-29 00:46:37 +08:00
metavar='N',
default=10,
type=int,
help='number of vehicles (default: 10)')
2019-06-14 18:40:30 +08:00
argparser.add_argument(
'-w', '--number-of-walkers',
metavar='W',
default=50,
type=int,
help='number of walkers (default: 50)')
2018-11-03 19:28:14 +08:00
argparser.add_argument(
'--safe',
action='store_true',
help='avoid spawning vehicles prone to accidents')
argparser.add_argument(
2019-07-01 22:23:47 +08:00
'--filterv',
metavar='PATTERN',
default='vehicle.*',
2019-07-01 22:23:47 +08:00
help='vehicles filter (default: "vehicle.*")')
argparser.add_argument(
'--filterw',
metavar='PATTERN',
default='walker.pedestrian.*',
2019-07-05 00:52:18 +08:00
help='pedestrians filter (default: "walker.pedestrian.*")')
2018-10-29 00:46:37 +08:00
args = argparser.parse_args()
logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.INFO)
vehicles_list = []
2019-07-01 22:23:47 +08:00
walkers_list = []
all_id = []
client = carla.Client(args.host, args.port)
client.set_timeout(2.0)
2018-10-29 00:46:37 +08:00
try:
world = client.get_world()
2019-07-01 22:23:47 +08:00
blueprints = world.get_blueprint_library().filter(args.filterv)
blueprintsWalkers = world.get_blueprint_library().filter(args.filterw)
2018-10-29 00:46:37 +08:00
2018-11-03 19:28:14 +08:00
if args.safe:
blueprints = [x for x in blueprints if int(x.get_attribute('number_of_wheels')) == 4]
blueprints = [x for x in blueprints if not x.id.endswith('isetta')]
blueprints = [x for x in blueprints if not x.id.endswith('carlacola')]
2018-11-03 19:28:14 +08:00
spawn_points = world.get_map().get_spawn_points()
number_of_spawn_points = len(spawn_points)
if args.number_of_vehicles < number_of_spawn_points:
random.shuffle(spawn_points)
elif args.number_of_vehicles > number_of_spawn_points:
msg = 'requested %d vehicles, but could only find %d spawn points'
logging.warning(msg, args.number_of_vehicles, number_of_spawn_points)
args.number_of_vehicles = number_of_spawn_points
# @todo cannot import these directly.
SpawnActor = carla.command.SpawnActor
SetAutopilot = carla.command.SetAutopilot
FutureActor = carla.command.FutureActor
# --------------
# Spawn vehicles
# --------------
batch = []
for n, transform in enumerate(spawn_points):
if n >= args.number_of_vehicles:
break
2018-10-29 00:46:37 +08:00
blueprint = random.choice(blueprints)
if blueprint.has_attribute('color'):
color = random.choice(blueprint.get_attribute('color').recommended_values)
blueprint.set_attribute('color', color)
if blueprint.has_attribute('driver_id'):
driver_id = random.choice(blueprint.get_attribute('driver_id').recommended_values)
blueprint.set_attribute('driver_id', driver_id)
Provide parent/attribute content of Actors via python interface While creating the new carla ros bridge some extensions became necessary within CARLA: The parent property of an actor via python interface is not yet filled. Therefore, the parent_id of Actors has to be transferred from the CARLA server via rpc interface. In addition, actor attributes are published via python interface. Changes in detail: carla/rpc/Actor.h: - add parent_id field to the Actor class for rpc transport TheNewCarlaServer.cpp: - fill the parent_id field with the appropriate value client/ActorList: - added GetActor() function to get an actor by id client/ActorVariant: - added actor_list optional parameter to Get() and MakeActor() function which allows to query for the parent actor in case the actor_list is available client/ActorAttribute: - solved problem of independent rpc::ActorAttribute* classes by introduction of ActorAttributeValueAccess class, to be able to reuse most of the functions for both ActorAttribueValues and ActorAttributes ActorBlueprintFunctionLibrary: - extended actor attributes by attribute 'role_name' having {autopilot, scenario, ego_vehicle} as recommended values for vehicles or {front,back,...} for sensors to be able to distiguish the different actors in a meaningful way when transferring to ROS topic names - extended vehicle attributes by not-modifiable attribute 'object_type' to be defined at blueprint creation time to provide ground truth object classification type PythonAPI: - libcarla: provide the actor attributes within python as dictionary - make use of role_name attribute to provide information required for ROS bridge to distinguish ego vehicle from others
2018-11-30 23:05:30 +08:00
blueprint.set_attribute('role_name', 'autopilot')
batch.append(SpawnActor(blueprint, transform).then(SetAutopilot(FutureActor, True)))
2018-10-29 22:00:46 +08:00
for response in client.apply_batch_sync(batch):
if response.error:
logging.error(response.error)
else:
vehicles_list.append(response.actor_id)
2018-10-30 19:00:00 +08:00
# -------------
2019-06-14 18:40:30 +08:00
# Spawn Walkers
# -------------
2019-11-20 17:59:00 +08:00
# some settings
percentagePedestriansRunning = 0.1 # how many pedestrians will run
percentagePedestriansCrossing = 0.01 # how many pedestrians will walk through the road
# 1. take all the random locations to spawn
2019-06-14 18:40:30 +08:00
spawn_points = []
for i in range(args.number_of_walkers):
spawn_point = carla.Transform()
loc = world.get_random_location_from_navigation()
if (loc != None):
spawn_point.location = loc
spawn_points.append(spawn_point)
# 2. we spawn the walker object
2019-07-02 22:06:35 +08:00
batch = []
walker_speed = []
2019-06-14 18:40:30 +08:00
for spawn_point in spawn_points:
2019-07-01 22:23:47 +08:00
walker_bp = random.choice(blueprintsWalkers)
# set as not invencible
if walker_bp.has_attribute('is_invincible'):
walker_bp.set_attribute('is_invincible', 'false')
# set the max speed
if walker_bp.has_attribute('speed'):
2019-11-20 17:59:00 +08:00
if (random.random() > percentagePedestriansRunning):
# walking
walker_speed.append(walker_bp.get_attribute('speed').recommended_values[1])
else:
# running
walker_speed.append(walker_bp.get_attribute('speed').recommended_values[2])
else:
print("Walker has no speed")
walker_speed.append(0.0)
2019-06-14 18:40:30 +08:00
batch.append(SpawnActor(walker_bp, spawn_point))
results = client.apply_batch_sync(batch, True)
walker_speed2 = []
2019-06-14 18:40:30 +08:00
for i in range(len(results)):
if results[i].error:
logging.error(results[i].error)
else:
2019-07-02 22:06:35 +08:00
walkers_list.append({"id": results[i].actor_id})
walker_speed2.append(walker_speed[i])
walker_speed = walker_speed2
# 3. we spawn the walker controller
2019-06-14 18:40:30 +08:00
batch = []
walker_controller_bp = world.get_blueprint_library().find('controller.ai.walker')
for i in range(len(walkers_list)):
batch.append(SpawnActor(walker_controller_bp, carla.Transform(), walkers_list[i]["id"]))
2019-06-14 18:40:30 +08:00
results = client.apply_batch_sync(batch, True)
for i in range(len(results)):
if results[i].error:
logging.error(results[i].error)
else:
walkers_list[i]["con"] = results[i].actor_id
# 4. we put altogether the walkers and controllers id to get the objects from their id
for i in range(len(walkers_list)):
all_id.append(walkers_list[i]["con"])
all_id.append(walkers_list[i]["id"])
2019-06-14 18:40:30 +08:00
all_actors = world.get_actors(all_id)
2019-07-03 21:51:26 +08:00
# wait for a tick to ensure client receives the last transform of the walkers we have just created
world.wait_for_tick()
# 5. initialize each controller and set target to walk to (list is [controler, actor, controller, actor ...])
# set how many pedestrians can cross the road
2019-11-20 17:59:00 +08:00
world.set_pedestrians_cross_factor(percentagePedestriansCrossing)
2019-06-19 16:22:27 +08:00
for i in range(0, len(all_id), 2):
# start walker
all_actors[i].start()
# set walk to random point
all_actors[i].go_to_location(world.get_random_location_from_navigation())
# max speed
all_actors[i].set_max_speed(float(walker_speed[int(i/2)]))
2019-06-14 18:40:30 +08:00
print('spawned %d vehicles and %d walkers, press Ctrl+C to exit.' % (len(vehicles_list), len(walkers_list)))
2019-06-14 18:40:30 +08:00
2018-10-30 19:00:00 +08:00
while True:
world.wait_for_tick()
2018-10-29 00:46:37 +08:00
finally:
print('\ndestroying %d vehicles' % len(vehicles_list))
client.apply_batch([carla.command.DestroyActor(x) for x in vehicles_list])
2018-10-29 00:46:37 +08:00
# stop walker controllers (list is [controller, actor, controller, actor ...])
2019-06-19 16:22:27 +08:00
for i in range(0, len(all_id), 2):
all_actors[i].stop()
print('\ndestroying %d walkers' % len(walkers_list))
2019-06-14 18:40:30 +08:00
client.apply_batch([carla.command.DestroyActor(x) for x in all_id])
2019-11-20 17:59:00 +08:00
time.sleep(0.5)
2019-06-21 18:26:00 +08:00
2018-10-29 00:46:37 +08:00
if __name__ == '__main__':
try:
main()
except KeyboardInterrupt:
pass
finally:
print('\ndone.')