use carla::{client::Client, geom::Location};
use std::time::Duration;
fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("=== Dynamic World Manipulation Integration Test ===\n");
let client = Client::connect("127.0.0.1", 2000, None)?;
let mut world = client.world()?;
println!("Connected to CARLA server");
println!("\n--- Test 1: Query world information ---");
test_world_info(&world)?;
println!("\n--- Test 2: Environment objects ---");
test_environment_objects(&world)?;
println!("\n--- Test 3: Traffic light manipulation ---");
test_traffic_lights(&mut world)?;
println!("\n--- Test 4: Weather manipulation ---");
test_weather_changes(&mut world)?;
println!("\n--- Test 5: Map operations ---");
test_map_operations(&world)?;
println!("\n=== All Tests Passed ===");
println!("✅ Integration test completed successfully!");
std::process::exit(0);
}
fn test_world_info(world: &carla::client::World) -> Result<(), Box<dyn std::error::Error>> {
let world_id = world.id()?;
println!("✓ World ID: {}", world_id);
let map = world.map().expect("map");
let map_name = map.name();
println!("✓ Map name: {}", map_name);
let spawn_points = map.recommended_spawn_points()?;
println!("✓ Available spawn points: {}", spawn_points.len());
let topology = map.topology()?;
println!("✓ Road topology segments: {}", topology.len());
assert!(!map_name.is_empty(), "Map name should not be empty");
assert!(!spawn_points.is_empty(), "Should have spawn points");
Ok(())
}
fn test_environment_objects(
world: &carla::client::World,
) -> Result<(), Box<dyn std::error::Error>> {
let objects = world.environment_objects(0xFF)?;
println!("✓ Found {} environment objects", objects.len());
if !objects.is_empty() {
let mut ids_to_toggle = Vec::new();
let count = objects.len().min(5);
for i in 0..count {
if let Some(obj) = objects.get(i) {
ids_to_toggle.push(obj.id());
}
}
if !ids_to_toggle.is_empty() {
println!(" Disabling {} objects...", ids_to_toggle.len());
world.enable_environment_objects(&ids_to_toggle, false)?;
std::thread::sleep(Duration::from_millis(500));
println!(" Re-enabling objects...");
world.enable_environment_objects(&ids_to_toggle, true)?;
println!("✓ Successfully toggled environment objects");
}
}
Ok(())
}
fn test_traffic_lights(world: &mut carla::client::World) -> Result<(), Box<dyn std::error::Error>> {
println!(" Freezing all traffic lights...");
world.freeze_all_traffic_lights(true)?;
std::thread::sleep(Duration::from_millis(500));
println!("✓ Traffic lights frozen");
println!(" Resetting all traffic lights...");
world.reset_all_traffic_lights()?;
std::thread::sleep(Duration::from_millis(500));
println!("✓ Traffic lights reset");
println!(" Unfreezing traffic lights...");
world.freeze_all_traffic_lights(false)?;
println!("✓ Traffic lights unfrozen");
Ok(())
}
fn test_weather_changes(
world: &mut carla::client::World,
) -> Result<(), Box<dyn std::error::Error>> {
let original_weather = world.weather()?;
println!(" Original weather:");
println!(" Cloudiness: {:.1}", original_weather.cloudiness);
println!(" Precipitation: {:.1}", original_weather.precipitation);
println!(
" Sun altitude: {:.1}°",
original_weather.sun_altitude_angle
);
println!("\n Setting rainy weather...");
let mut rainy_weather = world.weather()?;
rainy_weather.cloudiness = 90.0;
rainy_weather.precipitation = 80.0;
rainy_weather.precipitation_deposits = 50.0;
rainy_weather.wetness = 80.0;
world.set_weather(&rainy_weather)?;
std::thread::sleep(Duration::from_millis(500));
let current_weather = world.weather()?;
assert!(
(current_weather.cloudiness - 90.0).abs() < 1.0,
"Cloudiness should be set"
);
assert!(
(current_weather.precipitation - 80.0).abs() < 1.0,
"Precipitation should be set"
);
println!("✓ Rainy weather set successfully");
println!("\n Setting sunny weather...");
let mut sunny_weather = world.weather()?;
sunny_weather.cloudiness = 10.0;
sunny_weather.precipitation = 0.0;
sunny_weather.wetness = 0.0;
sunny_weather.sun_altitude_angle = 45.0;
world.set_weather(&sunny_weather)?;
std::thread::sleep(Duration::from_millis(500));
let current_weather = world.weather()?;
assert!(
(current_weather.cloudiness - 10.0).abs() < 1.0,
"Cloudiness should be low"
);
assert!(
current_weather.precipitation < 1.0,
"Precipitation should be zero"
);
println!("✓ Sunny weather set successfully");
println!("\n Restoring original weather...");
world.set_weather(&original_weather)?;
println!("✓ Weather restored");
Ok(())
}
fn test_map_operations(world: &carla::client::World) -> Result<(), Box<dyn std::error::Error>> {
let map = world.map()?;
let test_location = Location::new(0.0, 0.0, 0.0);
if let Some(waypoint) = map.waypoint_at(&test_location)?.as_ref() {
println!("✓ Found waypoint at test location");
println!(
" Waypoint location: ({:.1}, {:.1}, {:.1})",
waypoint.transform().location.x,
waypoint.transform().location.y,
waypoint.transform().location.z
);
let next_waypoints = waypoint.next(5.0)?;
println!("✓ Next waypoints: {} found", next_waypoints.len());
} else {
println!("⚠️ No waypoint found at (0,0,0) - using spawn point instead");
let spawn_points = map.recommended_spawn_points()?;
if let Some(spawn_point) = spawn_points.get(0)
&& let Some(waypoint) = map.waypoint_at(&spawn_point.location)?
{
println!("✓ Found waypoint at spawn point");
let next_waypoints = waypoint.next(5.0)?;
println!("✓ Next waypoints: {} found", next_waypoints.len());
}
}
let topology = map.topology()?;
if !topology.is_empty() {
println!("✓ Topology has {} road segments", topology.len());
if let Some((start_wp, _end_wp)) = topology.first() {
let next_wps = start_wp.next(1.0)?;
println!(
"✓ Can navigate from topology waypoint: {} next waypoints",
next_wps.len()
);
}
}
let all_waypoints = map.generate_waypoints(2.0)?;
println!("✓ Generated {} waypoints across map", all_waypoints.len());
assert!(!all_waypoints.is_empty(), "Should generate waypoints");
Ok(())
}