diff --git a/src/bike.rs b/src/bike.rs
index 6016dd9..d029adc 100644
--- a/src/bike.rs
+++ b/src/bike.rs
@@ -27,6 +27,9 @@ pub struct Steering;
 #[derive(Component)]
 pub struct Rearing;
 
+#[derive(Debug, Component, Clone, Default)]
+pub struct PreviousDisplacement(pub f32);
+
 #[derive(Debug, Resource, Reflect)]
 #[reflect(Resource)]
 pub struct SuspensionConfig {
@@ -41,8 +44,8 @@ impl Default for SuspensionConfig {
     fn default() -> Self {
         Self {
             rest_dist: REST_DISTANCE,
-            konstant: 50.0,
-            damping: 50.0,
+            konstant: 800.0,
+            damping: -100.0,
             front_attach: FRONT_ATTACH,
             rear_attach: REAR_ATTACH,
         }
@@ -54,7 +57,7 @@ fn spawn_bike(
     mut meshes: ResMut<Assets<Mesh>>,
     mut materials: ResMut<Assets<StandardMaterial>>,
 ) {
-    let pos = Vec3::new(0.0, 4.0, 0.0);
+    let pos = Vec3::new(0.0, 14.0, 0.0);
     let xform = Transform::from_translation(pos); //.with_rotation(Quat::from_rotation_z(0.0));
 
     let body_collider =
@@ -86,13 +89,7 @@ fn spawn_bike(
                 MeshMaterial3d(materials.add(color)),
             );
             builder.spawn(pbr_bundle);
-            spawn_wheels(
-                builder,
-                meshes,
-                materials,
-                Transform::default(),
-                builder.parent_entity(),
-            );
+            spawn_wheels(builder, meshes, materials, builder.parent_entity());
         });
 }
 
@@ -107,7 +104,7 @@ fn spawn_caster(
     let caster = ShapeCaster::new(collider, Vec3::ZERO, Quat::IDENTITY, direction)
         .with_query_filter(SpatialQueryFilter::from_excluded_entities([parent]));
 
-    let mut entity = commands.spawn((caster, xform));
+    let mut entity = commands.spawn((caster, xform, PreviousDisplacement(REST_DISTANCE)));
     if is_front {
         entity.insert((Steering, Name::new("front wheel")));
     } else {
@@ -119,19 +116,17 @@ fn spawn_wheels(
     commands: &mut ChildBuilder,
     mut meshes: ResMut<Assets<Mesh>>,
     mut materials: ResMut<Assets<StandardMaterial>>,
-    xform: Transform,
     body: Entity,
 ) {
     let (mesh, collider) = gen_tire();
 
     let front_rake = Vec3::new(0.0, -1.0, -0.57).normalize(); // about 30 degrees
-    let front_attach = xform.translation + xform.forward() * 0.7;
-    let front_wheel_pos = front_attach + (front_rake * REST_DISTANCE);
+    let front_wheel_pos = FRONT_ATTACH + (front_rake * REST_DISTANCE);
 
     spawn_caster(
         commands,
         collider.clone(),
-        Transform::from_translation(front_attach),
+        Transform::from_translation(FRONT_ATTACH),
         Dir3::new_unchecked(front_rake),
         body,
         true,
@@ -146,13 +141,13 @@ fn spawn_wheels(
     );
 
     let rear_rake = Vec3::new(0.0, -1.0, 0.57).normalize();
-    let rear_attach = xform.translation + xform.back() * 0.7;
-    let rear_wheel_pos = rear_attach + (rear_rake * REST_DISTANCE);
+    //let rear_attach = xform.translation + xform.back() * 0.7;
+    let rear_wheel_pos = REAR_ATTACH + (rear_rake * REST_DISTANCE);
 
     spawn_caster(
         commands,
         collider,
-        Transform::from_translation(rear_attach),
+        Transform::from_translation(REAR_ATTACH),
         Dir3::new_unchecked(rear_rake),
         body,
         false,
@@ -172,8 +167,8 @@ fn spawn_wheels(
 //-************************************************************************
 
 fn gen_tire() -> (Mesh, Collider) {
-    let tire_mesh: Mesh = Sphere::new(0.4).into();
-    let collider = Collider::sphere(0.4);
+    let tire_mesh: Mesh = Sphere::new(WHEEL_RADIUS).into();
+    let collider = Collider::sphere(WHEEL_RADIUS);
 
     (tire_mesh, collider)
 }
@@ -200,7 +195,7 @@ fn wheel_mesh(
         Mesh3d(meshes.add(tire_mesh)),
         MeshMaterial3d(materials.add(wheel_material.clone())),
         xform,
-        LinearVelocity::ZERO,
+        PreviousDisplacement::default(),
         wheel,
     ));
 }
@@ -210,6 +205,7 @@ pub struct CyberBikePlugin;
 impl Plugin for CyberBikePlugin {
     fn build(&self, app: &mut App) {
         app.init_resource::<SuspensionConfig>();
+        app.register_type::<SuspensionConfig>();
         app.add_systems(Startup, spawn_bike);
     }
 }
diff --git a/src/physics.rs b/src/physics.rs
index 2f22c7f..52d36f7 100644
--- a/src/physics.rs
+++ b/src/physics.rs
@@ -52,33 +52,22 @@ impl CatControllerState {
         self.roll_prev = error;
         (derivative, self.roll_integral)
     }
-
-    pub fn set_integral_limits(&mut self, roll: f32) {
-        self.roll_limit = roll;
-    }
 }
 
 mod systems {
     use std::f32::consts::{FRAC_PI_3, FRAC_PI_4};
 
     use avian3d::prelude::*;
-    use bevy::{math::VectorSpace, prelude::*};
+    use bevy::prelude::*;
 
     use super::{CatControllerSettings, CatControllerState, CyberLean};
     use crate::{
-        bike::{CyberBikeBody, CyberWheel, Rearing, Steering, SuspensionConfig},
+        bike::{
+            CyberBikeBody, CyberWheel, PreviousDisplacement, Rearing, Steering, SuspensionConfig,
+        },
         input::InputState,
     };
 
-    fn _yaw_to_angle(yaw: f32) -> f32 {
-        let v = yaw.powi(5) * FRAC_PI_3;
-        if v.is_normal() {
-            v
-        } else {
-            0.0
-        }
-    }
-
     fn rotate_point(pt: &Vec3, rot: &Quat) -> Vec3 {
         // thanks to https://danceswithcode.net/engineeringnotes/quaternions/quaternions.html
         let [x, y, z] = pt.normalize().to_array();
@@ -172,45 +161,39 @@ mod systems {
 
     pub(super) fn suspension(
         mut bike_body_query: Query<(&Transform, &mut ExternalForce), With<CyberBikeBody>>,
-        mut wheel_mesh_query: Query<
-            (&mut Transform, &LinearVelocity, &CyberWheel),
-            Without<CyberBikeBody>,
+        mut wheel_mesh_query: Query<(&mut Transform, &CyberWheel), Without<CyberBikeBody>>,
+        mut front_wheel_query: Query<
+            (&ShapeCaster, &ShapeHits, &mut PreviousDisplacement),
+            (With<Steering>, Without<Rearing>),
+        >,
+        mut rear_wheel_query: Query<
+            (&ShapeCaster, &ShapeHits, &mut PreviousDisplacement),
+            (With<Rearing>, Without<Steering>),
         >,
-        front_wheel_query: Query<(&ShapeCaster, &ShapeHits), (With<Steering>, Without<Rearing>)>,
-        rear_wheel_query: Query<(&ShapeCaster, &ShapeHits), (With<Rearing>, Without<Steering>)>,
         config: Res<SuspensionConfig>,
+        time: Res<Time>,
     ) {
+        let dt = time.delta().as_secs_f32();
         let mut front_wheel_xform = None;
         let mut rear_wheel_xform = None;
-        let mut front_wheel_vel = Vec3::ZERO;
-        let mut rear_wheel_vel = Vec3::ZERO;
-        for (xform, vel, wheel) in wheel_mesh_query.iter_mut() {
+        for (xform, wheel) in wheel_mesh_query.iter_mut() {
             match wheel {
                 CyberWheel::Front => {
                     front_wheel_xform = Some(xform);
-                    front_wheel_vel = **vel;
                 }
                 CyberWheel::Rear => {
                     rear_wheel_xform = Some(xform);
-                    rear_wheel_vel = **vel;
                 }
             }
         }
 
         let (bike_xform, mut bike_forces) = bike_body_query.single_mut();
 
-        for (caster, hits) in front_wheel_query.iter() {
+        for (caster, hits, mut prev) in front_wheel_query.iter_mut() {
             for hit in hits.iter() {
                 if let Some(ref mut xform) = front_wheel_xform {
-                    let force = suspension_force(
-                        caster,
-                        hit,
-                        &config,
-                        front_wheel_vel,
-                        xform,
-                        bike_xform.rotation,
-                        true,
-                    );
+                    let force =
+                        suspension_force(caster, hit, &config, &mut prev.0, dt, xform, true);
                     bike_forces.apply_force_at_point(
                         force,
                         caster.global_origin(),
@@ -220,18 +203,11 @@ mod systems {
             }
         }
 
-        for (caster, hits) in rear_wheel_query.iter() {
+        for (caster, hits, mut prev) in rear_wheel_query.iter_mut() {
             for hit in hits.iter() {
                 if let Some(ref mut xform) = rear_wheel_xform {
-                    let force = suspension_force(
-                        caster,
-                        hit,
-                        &config,
-                        rear_wheel_vel,
-                        xform,
-                        bike_xform.rotation,
-                        false,
-                    );
+                    let force =
+                        suspension_force(caster, hit, &config, &mut prev.0, dt, xform, false);
                     bike_forces.apply_force_at_point(
                         force,
                         caster.global_origin(),
@@ -246,12 +222,11 @@ mod systems {
         caster: &ShapeCaster,
         hit: &ShapeHitData,
         config: &SuspensionConfig,
-        wheel_vel: Vec3,
+        previous_dispacement: &mut f32,
+        dt: f32,
         wheel_xform: &mut Transform,
-        rotation: Quat,
         is_front: bool,
     ) -> Vec3 {
-        let mut loc = Vec3::ZERO;
         let mut up_force = Vec3::ZERO;
         let attach = if is_front {
             config.front_attach
@@ -260,16 +235,18 @@ mod systems {
         };
         let dist = hit.distance;
         let cdir = caster.direction.as_vec3();
-        let dir = rotation.mul_vec3(cdir);
-        if dist < config.rest_dist {
-            loc = attach + (cdir * dist);
+        let dir = caster.global_direction().as_vec3();
+        let loc = if dist < config.rest_dist {
             let displacement = config.rest_dist - dist;
-            let damper_vel = dir.dot(wheel_vel);
+            let damper_vel = (displacement - *previous_dispacement) / dt;
+            dbg!(damper_vel);
+            *previous_dispacement = displacement;
             let mag = config.konstant * displacement - config.damping * damper_vel;
             up_force = -dir * mag;
+            attach + (cdir * dist)
         } else {
-            loc = attach + (cdir * config.rest_dist);
-        }
+            attach + (cdir * config.rest_dist)
+        };
 
         wheel_xform.translation = loc;
 
@@ -290,9 +267,6 @@ impl Plugin for CyberPhysicsPlugin {
             .register_type::<CyberLean>()
             .add_plugins((PhysicsPlugins::default(), PhysicsDebugPlugin::default()))
             .insert_resource(SubstepCount(12))
-            .add_systems(Startup, |mut gravity: ResMut<Gravity>| {
-                gravity.0 *= 0.01;
-            })
             .add_systems(Update, (apply_lean, calculate_lean, suspension));
     }
 }