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

Create a random engine instance for each vehicle #126

Merged
merged 4 commits into from
Jan 23, 2018
Merged
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
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,5 @@ Util/Build
.vs
__pycache__
_benchmarks_results
_images
_images*
core

168 changes: 168 additions & 0 deletions PythonClient/test/test_repeatability.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
#!/usr/bin/env python3

# Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma de
# Barcelona (UAB), and the INTEL Visual Computing Lab.
#
# This work is licensed under the terms of the MIT license.
# For a copy, see <https://opensource.org/licenses/MIT>.

"""Client that runs two servers simultaneously to test repeatability."""

import argparse
import logging
import os
import random
import sys
import time

sys.path.append(os.path.join(os.path.dirname(__file__), '..'))

from carla.client import make_carla_client
from carla.sensor import Camera, Image
from carla.settings import CarlaSettings
from carla.tcp import TCPConnectionError


def run_carla_clients(args):
filename = '_images_repeatability/server{:d}/{:0>6d}.png'
with make_carla_client(args.host1, args.port1) as client1:
logging.info('1st client connected')
with make_carla_client(args.host2, args.port2) as client2:
logging.info('2nd client connected')

settings = CarlaSettings()
settings.set(
SynchronousMode=True,
SendNonPlayerAgentsInfo=True,
NumberOfVehicles=50,
NumberOfPedestrians=50,
WeatherId=random.choice([1, 3, 7, 8, 14]))
settings.randomize_seeds()

if args.images_to_disk:
camera = Camera('DefaultCamera')
camera.set_image_size(800, 600)
settings.add_sensor(camera)

scene1 = client1.load_settings(settings)
scene2 = client2.load_settings(settings)

number_of_player_starts = len(scene1.player_start_spots)
assert number_of_player_starts == len(scene2.player_start_spots)
player_start = random.randint(0, max(0, number_of_player_starts - 1))
logging.info(
'start episode at %d/%d player start (run forever, press ctrl+c to cancel)',
player_start,
number_of_player_starts)

client1.start_episode(player_start)
client2.start_episode(player_start)

frame = 0
while True:
frame += 1

meas1, sensor_data1 = client1.read_data()
meas2, sensor_data2 = client2.read_data()

player1 = meas1.player_measurements
player2 = meas2.player_measurements

images1 = [x for x in sensor_data1.values() if isinstance(x, Image)]
images2 = [x for x in sensor_data2.values() if isinstance(x, Image)]

control1 = player1.autopilot_control
control2 = player2.autopilot_control

try:
assert len(images1) == len(images2)
assert len(meas1.non_player_agents) == len(meas2.non_player_agents)
assert player1.transform.location.x == player2.transform.location.x
assert player1.transform.location.y == player2.transform.location.y
assert player1.transform.location.z == player2.transform.location.z
assert control1.steer == control2.steer
assert control1.throttle == control2.throttle
assert control1.brake == control2.brake
assert control1.hand_brake == control2.hand_brake
assert control1.reverse == control2.reverse
except AssertionError:
logging.exception('assertion failed')

if args.images_to_disk:
assert len(images1) == 1
images1[0].save_to_disk(filename.format(1, frame))
images2[0].save_to_disk(filename.format(2, frame))

client1.send_control(control1)
client2.send_control(control2)


def main():
argparser = argparse.ArgumentParser(description=__doc__)
argparser.add_argument(
'-v', '--verbose',
action='store_true',
dest='debug',
help='print debug information')
argparser.add_argument(
'--log',
metavar='LOG_FILE',
default=None,
help='print output to file')
argparser.add_argument(
'--host1',
metavar='H',
default='127.0.0.1',
help='IP of the first host server (default: 127.0.0.1)')
argparser.add_argument(
'-p1', '--port1',
metavar='P',
default=2000,
type=int,
help='TCP port to listen to the first server (default: 2000)')
argparser.add_argument(
'--host2',
metavar='H',
default='127.0.0.1',
help='IP of the second host server (default: 127.0.0.1)')
argparser.add_argument(
'-p2', '--port2',
metavar='P',
default=3000,
type=int,
help='TCP port to listen to the second server (default: 3000)')
argparser.add_argument(
'-i', '--images-to-disk',
action='store_true',
help='save images to disk')

args = argparser.parse_args()

logging_config = {
'format': '%(levelname)s: %(message)s',
'level': logging.DEBUG if args.debug else logging.INFO
}
if args.log:
logging_config['filename'] = args.log
logging_config['filemode'] = 'w+'
logging.basicConfig(**logging_config)

logging.info('listening to 1st server at %s:%s', args.host1, args.port1)
logging.info('listening to 2nd server at %s:%s', args.host2, args.port2)

while True:
try:

run_carla_clients(args)

except TCPConnectionError as error:
logging.error(error)
time.sleep(1)


if __name__ == '__main__':

try:
main()
except KeyboardInterrupt:
print('\nCancelled by user. Bye!')
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ void AVehicleSpawnerBase::SpawnVehicleAtSpawnPoint(
Vehicle->SpawnDefaultController();
auto Controller = GetController(Vehicle);
if (Controller != nullptr) { // Sometimes fails...
Controller->SetRandomEngine(GetRandomEngine());
Controller->GetRandomEngine()->Seed(GetRandomEngine()->GenerateSeed());
Controller->SetRoadMap(GetRoadMap());
Controller->SetAutopilot(true);
Vehicles.Add(Vehicle);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ static void ClearQueue(std::queue<T> &Queue)
AWheeledVehicleAIController::AWheeledVehicleAIController(const FObjectInitializer& ObjectInitializer) :
Super(ObjectInitializer)
{
RandomEngine = CreateDefaultSubobject<URandomEngine>(TEXT("RandomEngine"));

PrimaryActorTick.bCanEverTick = true;
PrimaryActorTick.TickGroup = TG_PrePhysics;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,14 +98,10 @@ class CARLA_API AWheeledVehicleAIController : public APlayerController
/// @{
public:

void SetRandomEngine(URandomEngine *InRandomEngine)
{
RandomEngine = InRandomEngine;
}

UFUNCTION(Category = "Random Engine", BlueprintCallable)
URandomEngine *GetRandomEngine()
{
check(RandomEngine != nullptr);
return RandomEngine;
}

Expand Down Expand Up @@ -221,13 +217,13 @@ class CARLA_API AWheeledVehicleAIController : public APlayerController
private:

UPROPERTY()
ACarlaWheeledVehicle *Vehicle;
ACarlaWheeledVehicle *Vehicle = nullptr;

UPROPERTY()
URoadMap *RoadMap;
URoadMap *RoadMap = nullptr;

UPROPERTY()
URandomEngine *RandomEngine;
URandomEngine *RandomEngine = nullptr;

UPROPERTY(VisibleAnywhere)
bool bAutopilotEnabled = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,8 @@ void ACarlaGameModeBase::BeginPlay()
VehicleSpawner->SetSeed(CarlaSettings.SeedVehicles);
VehicleSpawner->SetRoadMap(RoadMap);
if (PlayerController != nullptr) {
PlayerController->SetRandomEngine(VehicleSpawner->GetRandomEngine());
PlayerController->GetRandomEngine()->Seed(
VehicleSpawner->GetRandomEngine()->GenerateSeed());
}
} else {
UE_LOG(LogCarla, Error, TEXT("Missing vehicle spawner actor!"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,10 @@ int32 URandomEngine::GenerateRandomSeed()
std::numeric_limits<int32>::max());
return Distribution(RandomDevice);
}

int32 URandomEngine::GenerateSeed()
{
return GetUniformIntInRange(
std::numeric_limits<int32>::lowest(),
std::numeric_limits<int32>::max());
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,19 @@ class URandomEngine : public UObject
public:

// ===========================================================================
/// @name Set and get seed
/// @name Seed
// ===========================================================================
/// @{

/// Generate a non-deterministic random seed.
UFUNCTION(BlueprintCallable)
static int32 GenerateRandomSeed();

/// Generate a seed derived from previous seed.
UFUNCTION(BlueprintCallable)
int32 GenerateSeed();

/// Seed the random engine.
UFUNCTION(BlueprintCallable)
void Seed(int32 InSeed)
{
Expand Down