traci-rs 0.2.0

Pure Rust client library for the SUMO TraCI protocol
Documentation
// SPDX-License-Identifier: EPL-2.0
// Simple SUMO simulation example using traci-rs.
//
// Before running this example, start SUMO with a TraCI server:
//
//   sumo --net-file net.xml \
//        --route-files routes.rou.xml \
//        --remote-port 8813 \
//        --num-clients 1
//
// Then run:
//   cargo run --example simple_simulation

use traci_rs::TraciClient;

const NUM_VEHICLES: usize = 5;

fn main() -> Result<(), traci_rs::TraciError> {
    let mut client = TraciClient::connect("127.0.0.1", 8813)?;
    println!("Connected to SUMO TraCI server.");

    client.set_order(1)?;

    let (api_version, sumo_version) = client.get_version()?;
    println!("TraCI API version : {api_version}");
    println!("SUMO version      : {sumo_version}");

    // Add a route spanning the whole network, then insert 5 vehicles on it.
    // Pick the first available route (already defined in the .rou.xml file),
    // or create a minimal one-edge route if the network exposes its edges.
    let routes = client.route_get_id_list()?;
    let route_id = if let Some(r) = routes.first() {
        r.clone()
    } else {
        // Fallback: create a single-edge route using the first network edge.
        let edges = client.edge_get_id_list()?;
        let first_edge = edges.into_iter()
            .find(|e| !e.starts_with(':'))
            .expect("no drivable edge found in network");
        client.route_add("route_traci", &[&first_edge])?;
        "route_traci".to_string()
    };
    println!("Using route '{route_id}'");

    for i in 0..NUM_VEHICLES {
        let vid = format!("traci_veh_{i}");
        client.vehicle_add(&vid, &route_id, "DEFAULT_VEHTYPE")?;
        println!("Added vehicle '{vid}'");
    }

    let mut step = 0u32;
    // simulation_step returns Ok(false) when SUMO sends CMD_CLOSE at end-of-sim.
    while client.simulation_step(0.0)? {
        step += 1;

        let ids = client.vehicle_get_id_list()?;

        // Stop as soon as all vehicles have left the network.
        if ids.is_empty() {
            println!("All vehicles finished. Stopping after {step} steps.");
            break;
        }

        println!("--- Step {:>4}  ({} vehicles) ---", step, ids.len());
        for id in &ids {
            let pos   = client.vehicle_get_position(id)?;
            let speed = client.vehicle_get_speed(id)?;
            println!(
                "  Vehicle {:20}  pos=({:8.2}, {:8.2})  speed={:.2} m/s",
                id, pos.x, pos.y, speed
            );
        }
    }

    client.close()?;
    Ok(())
}