use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum BipedalTerrain {
Flat,
Rough,
Hardcore,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BipedalWalkerConfig {
pub terrain: BipedalTerrain,
pub hull_friction: f32,
pub leg_friction: f32,
pub motors_torque: f32,
pub speed_hip: f32,
pub speed_knee: f32,
pub lidar_range: f32,
pub seed: u64,
pub max_steps: usize,
pub dt: f32,
pub gravity: f32,
}
impl Default for BipedalWalkerConfig {
fn default() -> Self {
Self {
terrain: BipedalTerrain::Flat,
hull_friction: 0.1,
leg_friction: 0.2,
motors_torque: 80.0,
speed_hip: 4.0,
speed_knee: 6.0,
lidar_range: 160.0,
seed: 0,
max_steps: 1600,
dt: 1.0 / 50.0,
gravity: -9.8,
}
}
}
impl BipedalWalkerConfig {
pub fn builder() -> BipedalWalkerConfigBuilder {
BipedalWalkerConfigBuilder {
inner: BipedalWalkerConfig::default(),
}
}
}
#[derive(Debug, Clone)]
pub struct BipedalWalkerConfigBuilder {
inner: BipedalWalkerConfig,
}
impl BipedalWalkerConfigBuilder {
pub fn terrain(mut self, terrain: BipedalTerrain) -> Self {
self.inner.terrain = terrain;
self
}
pub fn seed(mut self, seed: u64) -> Self {
self.inner.seed = seed;
self
}
pub fn max_steps(mut self, max_steps: usize) -> Self {
self.inner.max_steps = max_steps;
self
}
pub fn motors_torque(mut self, torque: f32) -> Self {
self.inner.motors_torque = torque;
self
}
pub fn lidar_range(mut self, range: f32) -> Self {
self.inner.lidar_range = range;
self
}
pub fn build(self) -> BipedalWalkerConfig {
self.inner
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_default_config() {
let cfg = BipedalWalkerConfig::default();
assert_eq!(cfg.terrain, BipedalTerrain::Flat);
assert_eq!(cfg.max_steps, 1600);
assert!(cfg.dt > 0.0);
}
#[test]
fn test_builder() {
let cfg = BipedalWalkerConfig::builder()
.terrain(BipedalTerrain::Hardcore)
.seed(42)
.max_steps(500)
.build();
assert_eq!(cfg.terrain, BipedalTerrain::Hardcore);
assert_eq!(cfg.seed, 42);
assert_eq!(cfg.max_steps, 500);
}
}