Skip to main content

v0.37.0 Release Notes

EnerOS v0.37.0

Release Date: 2026-05-23 Codename: TwinX Git Tag: v0.37.0 Support Status: Stable Total Crates: 90 (6 new) Test Cases: 11400+ (700 new)

Overview

EnerOS v0.37.0 “TwinX” is a digital twin enhancement-focused release, upgrading EnerOS’s digital twin capabilities from “2D data mapping” to a complete digital twin system of “3D visualization + physics simulation + immersive interaction.” This release enables EnerOS to build a 3D digital twin that corresponds 1:1 with the physical grid, supporting scenarios such as operations inspection, training drills, and plan rehearsals.

The core design philosophy of the TwinX release is “virtual-real synchronization + physical consistency” — the digital twin is not only visually consistent with physical equipment, but also follows physical laws in behavior. The twin’s state changes are driven by real-time data, and the twin’s operation rehearsals are guaranteed by physics simulation, ensuring “what you see in digital space is what happens in physical space, and the rehearsal results of operations in digital space are the results of operations in physical space.”

This release introduces five core capabilities: 3D Visualization Engine, Physics Simulation Integration, AR/VR Interface, Real-time Synchronization Framework, and Twin Scenario Orchestration. All capabilities are implemented through five new crates: eneros-twinx, eneros-twinx-3d, eneros-twinx-physics, eneros-twinx-arvr, and eneros-twinx-sync.

Key Metrics

MetricValueDescription
3D scene loading1.2s1000 devices
Real-time sync latency50msState refresh
Physics simulation FPS60 FPSReal-time rendering
AR end-to-end latency35msIncludes rendering
New Crates6Twin-related
New tests700+Includes 80 end-to-end

New Features

1. 3D Visualization Engine

Adds the eneros-twinx-3d crate, providing a WebGPU-based 3D rendering engine, supporting fine-grained 3D modeling and real-time rendering of substations, lines, and equipment.

3D Scene Construction

use eneros_twinx_3d::{Scene3D, SceneBuilder, Camera, Lighting};

let mut scene = SceneBuilder::new()
    .background(Environment::Sky)
    .lighting(Lighting::sun_position(now()))
    .camera(Camera::orbit().target(0.0, 10.0, 0.0).distance(50.0))
    .build().await?;

// Auto-generate 3D scene from topology
scene.load_from_topology(&network).await?;

// Load equipment 3D models
scene.load_model("transformer-110kv", "/models/transformer.glb").await?;
scene.load_model("breaker-vacuum", "/models/breaker.glb").await?;

// Bind equipment instances to 3D objects
for equipment in &network.equipments {
    scene.bind_instance(equipment.id, &equipment.model_3d, equipment.position)?;
}

scene.start_render().await?;

3D Object Properties

PropertyTypeDescription
geometryMesh3D geometry
materialPBRPhysical material
transformMatrix4x4Position/rotation/scale
animationSkeletonSkeletal animation
interactionColliderCollision detection
metadataJSONDevice info

State-driven Visualization

// Device state drives 3D appearance in real-time
scene.on_state_change(|device_id, state| {
    let obj = scene.get_object(device_id)?;
    match state {
        DeviceState::Energized => obj.set_material(Material::emissive(Color::green())),
        DeviceState::Deenergized => obj.set_material(Material::standard(Color::gray())),
        DeviceState::Fault => {
            obj.set_material(Material::emissive(Color::red()));
            obj.start_animation("alarm_blink")?;
        }
        DeviceState::Maintenance => obj.set_material(Material::emissive(Color::yellow())),
    }
}).await?;

// Real-time data drives dynamic effects
scene.bind_data("transformer-001", "temperature", |obj, temp| {
    // Higher temperature, stronger winding glow
    let intensity = (temp - 40.0) / 60.0;
    obj.set_emissive_intensity(intensity.max(0.0));
}).await?;

2. Physics Simulation Integration

Adds the eneros-twinx-physics crate, integrating a physics simulation engine into the digital twin, making equipment behavior in the 3D scene conform to physical laws.

Simulation Capabilities

Simulation TypeEngineApplication ScenarioAccuracy
Rigid body dynamicsrapierEquipment motion, collisionHigh
Fluid dynamicsIn-houseOil flow, airflowMedium
Electromagnetic fieldFEMElectromagnetic field distributionHigh
ThermodynamicsFDMTemperature field distributionMedium
Acousticsray-tracingNoise propagationMedium

Physics Simulation Example

use eneros_twinx_physics::{PhysicsWorld, RigidBody, Collider};

let mut physics = PhysicsWorld::new();
physics.gravity(Vec3::new(0.0, -9.81, 0.0));

// Simulate kinematics of switch operation
let breaker = RigidBody::dynamic()
    .mass(5.0)
    .collider(Collider::box_(0.2, 0.5, 0.2))
    .build();

physics.add_body(breaker);

// Simulate switch opening process
physics.apply_force("breaker-arm", Vec3::new(0.0, 500.0, 0.0));
let trajectory = physics.simulate(Duration::milliseconds(100)).await?;

// For operations training: observe mechanical stress during opening
for step in &trajectory {
    println!("t={:.3}s position={:?} stress={:.1} N",
        step.time, step.position, step.stress);
}

3. AR/VR Interface

Adds the eneros-twinx-arvr crate, providing Augmented Reality (AR) and Virtual Reality (VR) interfaces, supporting operators to interact with the digital twin through immersive devices.

AR Inspection

use eneros_twinx_arvr::{ArSession, ArConfig, Overlay};

let ar = ArSession::new(ArConfig {
    device: ArDevice::Hololens3,
    anchor_strategy: AnchorStrategy::SpatialMapping,
    hand_tracking: true,
    voice_commands: true,
}).await?;

// Start AR inspection
ar.start_inspection(StationId::from("SS-110-01")).await?;

// Device information overlay
ar.on_gaze(|device_id| {
    let info = phm.get_profile(device_id).await?;
    ar.show_overlay(Overlay::info_panel()
        .title(&info.name)
        .field("Health score", format!("{:.1}", info.health_score.value))
        .field("Temperature", format!("{:.1} C", info.current_temp))
        .field("Load rate", format!("{:.1}%", info.load_rate))
        .anchor(device_id))?;
}).await?;

// Voice commands
ar.on_voice("Show internal structure", |_| {
    ar.set_xray_mode(true);  // See through internal structure
}).await?;

ar.on_voice("Replay last fault", |_| {
    ar.replay_event("fault-2026-05-20-001");
}).await?;

VR Training

use eneros_twinx_arvr::{VrSession, VrScenario};

let vr = VrSession::new(VrConfig {
    device: VrDevice::Quest3,
    teleport: true,
    physics_interaction: true,
}).await?;

// Load training scenario
vr.load_scenario(VrScenario::switch_operation_training()).await?;

// Trainee action evaluation
vr.on_action(|action| {
    match action {
        Action::ApproachDevice(id) => log::info!("Approaching device {}", id),
        Action::OpenSwitch(id) => {
            // Validate operation sequence
            if !procedure.check_step("verify_deenergized")? {
                vr.show_warning("Please verify de-energized first!");
                return;
            }
            vr.execute_switch_operation(id).await?;
        }
        Action::Complete => {
            let score = procedure.evaluate();
            vr.show_result(score);
        }
    }
}).await?;

AR/VR Capability Comparison

CapabilityARVRDescription
Reality overlaySupportedNot supportedAR core capability
Immersive scenePartialCompleteVR core capability
Gesture interactionSupportedSupportedBoth support
Voice controlSupportedSupportedBoth support
Multi-user collaborationSupportedSupportedShared space

4. Real-time Synchronization Framework

Adds the eneros-twinx-sync crate, ensuring real-time synchronization between the digital twin and the physical grid, supporting sub-second state refresh.

Synchronization Architecture

use eneros_twinx_sync::{SyncEngine, SyncConfig, SyncSource};

let sync = SyncEngine::new(&ctx)
    .config(SyncConfig {
        refresh_rate: 20,  // 20 FPS
        max_latency: Duration::milliseconds(100),
        interpolation: true,  // Inter-frame interpolation
        extrapolation: false, // No extrapolation
        priority: PriorityBy::Criticality,
    })
    .source(SyncSource::PmuStream { resolution: Duration::milliseconds(20) })
    .source(SyncSource::ScadaPolling { interval: Duration::seconds(2) })
    .source(SyncSource::TopologyEvents { realtime: true })
    .build().await?;

// Start real-time sync
sync.start().await?;

// Sync status monitoring
sync.on_metrics(|m| {
    println!("Sync latency: {:.0}ms, dropped frames: {}, FPS: {:.1}",
        m.latency_p99, m.dropped_frames, m.actual_fps);
}).await?;

Synchronization Priority

Data TypePriorityRefresh FrequencyDescription
Protection actionHighestReal-timeImmediate sync
Switch statusHigh100msTopology change
Voltage/currentMedium20msPMU data
Equipment temperatureLow5sSlowly changing data
Environmental dataLowest60sMeteorological data

5. Twin Scenario Orchestration

Adds the eneros-twinx crate (twin core), providing scenario orchestration capabilities, supporting advanced scenarios such as rehearsal, playback, and comparison.

Operation Rehearsal

use eneros_twinx::{ScenarioEngine, Scenario, ScenarioResult};

let engine = ScenarioEngine::new(&ctx);

// Build operation rehearsal scenario
let scenario = Scenario::new("switch-maintenance-001")
    .description("110kV Bus 5 maintenance transfer operation")
    .step(Step::verify_deenergized(BusId::from(5)))
    .step(Step::ground(BusId::from(5)))
    .step(Step::maintenance_window(Duration::hours(4)))
    .step(Step::remove_ground(BusId::from(5)))
    .step(Step::energize(BusId::from(5)));

// Dry run in twin
let result: ScenarioResult = engine.dry_run(&scenario).await?;

println!("Rehearsal result:");
println!("  Estimated duration: {:?}", result.estimated_duration);
println!("  Impact scope: {} devices", result.affected_devices);
println!("  Risk assessment: {:?}", result.risk_level);
println!("  Constraint check: {}", if result.constraints_ok { "Passed" } else { "Violation" });

if result.has_warnings() {
    for w in &result.warnings {
        println!("  Warning: {}", w);
    }
}

Historical Playback

// Replay a fault event
let replay = engine.replay_event("fault-2026-05-20-001")
    .speed(0.5)           // 0.5x speed
    .show_data_overlay(true)
    .highlight_cascade(true)  // Highlight cascading fault path
    .start().await?;

Scenario Comparison

// Compare execution effects of two dispatching plans
let comparison = engine.compare(
    Scenario::from_schedule(schedule_a),
    Scenario::from_schedule(schedule_b),
).await?;

println!("Plan comparison:");
println!("{:<15} {:<15} {:<15}", "Metric", "Plan A", "Plan B");
println!("{:<15} {:<15.0} {:<15.0}", "Cost(CNY)", a.cost, b.cost);
println!("{:<15} {:<15.1}% {:<15.1}%", "Utilization", a.renewable, b.renewable);
println!("{:<15} {:<15.2} {:<15.2}", "Loss(MW)", a.loss, b.loss);

Improvements

  • Topology Engine: Supports 3D coordinate properties, automatic equipment positioning
  • Timeseries Engine: Dedicated twin sync channel, latency reduced by 60%
  • Equipment Model: Added 3D model templates for 150+ devices
  • Security Gateway: Strict isolation between twin operation rehearsal and actual control
  • Observability: Twin state integrated into Grafana 3D dashboards

Bug Fixes

  • Fixed eneros-twinx-3d frame rate drops in large-scale scenes (#3703)
  • Fixed eneros-twinx-physics rigid body simulation penetration during high-speed collisions (#3710)
  • Fixed eneros-twinx-arvr AR anchor loss in low-light environments (#3716)
  • Fixed eneros-twinx-sync inter-frame interpolation anomalies during network jitter (#3722)
  • Fixed eneros-twinx scenario playback timeline errors across time zones (#3728)

Breaking Changes

  • Scene3D::load_from_topology: Parameter adds coordinate_system option
  • PhysicsWorld::simulate: Return type changed from Trajectory to Result<Trajectory>
  • ArSession::start_inspection: Parameter changed from &str to StationId

Upgrade Guide

  1. Update the eneros dependency in Cargo.toml to 0.37.0
  2. Install 3D model resource pack: eneros twinx install-models
  3. Configure AR/VR device connections in eneros.toml
  4. Run eneros twinx build-scene to build 3D scene

Acknowledgments

Thanks to the 36 contributors who submitted 550+ commits, and to the 3D modeling team for device model resources.