use anyhow::Result;
use carla::{
client::{ActorBase, Client, Vehicle},
rpc::VehicleControl,
};
use carla_ackermann::{TargetRequest, VehicleController};
use clap::Parser;
use rand::prelude::*;
#[derive(Parser)]
struct Opts {
#[clap(default_value = "127.0.0.1")]
pub address: String,
#[clap(default_value = "2000")]
pub port: u16,
}
fn main() -> Result<()> {
let Opts { address, port } = Opts::parse();
let client = Client::connect(&address, port, None);
let mut world = client.world();
let mut vehicle: Vehicle = {
let mut rng = rand::thread_rng();
let spawn_point = {
let spawn_points = world.map().recommended_spawn_points();
let index = rng.gen_range(0..spawn_points.len());
spawn_points.get(index).unwrap()
};
world
.actor_builder("vehicle.tesla.model3")?
.spawn_vehicle(&spawn_point)?
};
let mut controller = VehicleController::from_physics_control(&vehicle.physics_control(), None);
controller.set_target(TargetRequest {
steering_angle: 0.0,
speed: 5.0,
accel: 1.0,
});
let snapshot = world.wait_for_tick();
let mut world_id = snapshot.id();
let mut time_secs = snapshot.timestamp().elapsed_seconds;
loop {
let curr_id = snapshot.id();
let curr_secs = snapshot.timestamp().elapsed_seconds;
let time_delta_secs = if curr_id != world_id {
0.0
} else {
curr_secs - time_secs
};
world_id = curr_id;
time_secs = curr_secs;
let speed = vehicle.velocity().norm();
let (_, pitch, _) = vehicle.transform().rotation.euler_angles();
let (output, _report) = controller.step(time_delta_secs, speed as f64, pitch as f64);
vehicle.apply_control(&VehicleControl {
throttle: output.throttle as f32,
steer: output.steer as f32,
brake: output.brake as f32,
hand_brake: output.hand_brake,
reverse: output.reverse,
manual_gear_shift: false,
gear: 0,
});
}
}