Skip to content

Instantly share code, notes, and snippets.

@Kielan
Created December 26, 2025 15:51
Show Gist options
  • Select an option

  • Save Kielan/467d820a2a1fce140c4244ccdeee0761 to your computer and use it in GitHub Desktop.

Select an option

Save Kielan/467d820a2a1fce140c4244ccdeee0761 to your computer and use it in GitHub Desktop.
ChatGPT low-power energy-harvesting simulation in Rust + Bevy [ Environment ] ↓ [ Humidity Gradient ] ↓ [ Harvester (µW source, noisy) ] ↓ [ Energy Storage (capacitor) ] ↓ [ Load (MCU / radio / sensor) ]
use bevy::prelude::*;
#[derive(Component)]
struct Environment {
humidity: f32, // 0.0 - 1.0
temperature: f32, // °C
}
#[derive(Component)]
struct Harvester {
efficiency: f32, // 0.0 - 1.0
max_power_uw: f32, // microwatts
}
#[derive(Component)]
struct Storage {
energy_uj: f32, // microjoules
capacity_uj: f32,
}
#[derive(Component)]
struct Load {
active: bool,
draw_uw: f32,
}
fn harvest_power(env: &Environment, harvester: &Harvester) -> f32 {
let gradient = env.humidity * (1.0 - env.humidity);
let noise = rand::random::<f32>() * 0.2 + 0.9;
harvester.max_power_uw * gradient * harvester.efficiency * noise
}
fn environment_system(mut env: Query<&mut Environment>, time: Res<Time>) {
for mut env in env.iter_mut() {
env.humidity += (rand::random::<f32>() - 0.5) * 0.001;
env.humidity = env.humidity.clamp(0.0, 1.0);
}
}
fn harvesting_system(
time: Res<Time>,
env: Query<&Environment>,
mut query: Query<(&Harvester, &mut Storage)>
) {
let env = env.single();
let dt = time.delta_seconds();
for (harvester, mut storage) in query.iter_mut() {
let power_uw = harvest_power(env, harvester);
let energy_gained = power_uw * dt;
storage.energy_uj =
(storage.energy_uj + energy_gained)
.min(storage.capacity_uj);
}
}
fn load_system(
time: Res<Time>,
mut query: Query<(&mut Storage, &mut Load)>
) {
let dt = time.delta_seconds();
for (mut storage, mut load) in query.iter_mut() {
if load.active {
let drain = load.draw_uw * dt;
storage.energy_uj -= drain;
if storage.energy_uj <= 0.0 {
storage.energy_uj = 0.0;
load.active = false; // brownout
}
}
}
}
fn duty_cycle_system(
mut query: Query<(&Storage, &mut Load)>,
) {
for (storage, mut load) in query.iter_mut() {
if storage.energy_uj > 50.0 {
load.active = true;
} else {
load.active = false;
}
}
}
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_systems(Update, (
environment_system,
harvesting_system,
load_system,
duty_cycle_system,
))
.add_systems(Startup, setup)
.run();
}
fn setup(mut commands: Commands) {
commands.spawn(Environment {
humidity: 0.6,
temperature: 22.0,
});
commands.spawn((
Harvester {
efficiency: 0.15,
max_power_uw: 5.0,
},
Storage {
energy_uj: 10.0,
capacity_uj: 200.0,
},
Load {
active: false,
draw_uw: 20.0,
},
));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment