Browse Source

autotest: update rover sim for turning circle based steering

more realistic modelling of a rover
master
Andrew Tridgell 12 years ago
parent
commit
761bd75a3a
  1. 69
      Tools/autotest/pysim/rover.py

69
Tools/autotest/pysim/rover.py

@ -5,23 +5,61 @@ simple rover simulator core @@ -5,23 +5,61 @@ simple rover simulator core
from aircraft import Aircraft
import util, time, math
from math import degrees, radians
from math import degrees, radians, sin, cos, pi, asin
from rotmat import Vector3, Matrix3
class Rover(Aircraft):
'''a simple rover'''
def __init__(self,
max_speed=13,
max_accel=10,
max_turn_rate=100,
max_accel=9,
wheelbase=0.335,
wheeltrack=0.296,
max_wheel_turn=35,
skid_steering=False):
Aircraft.__init__(self)
self.max_speed = max_speed
self.max_accel = max_accel
self.max_turn_rate = max_turn_rate
self.wheelbase = wheelbase
self.wheeltrack = wheeltrack
self.max_wheel_turn = max_wheel_turn
self.last_time = time.time()
self.skid_steering = skid_steering
def turn_circle(self, steering_angle):
'''return turning circle (diameter) in meters for steering_angle in degrees
'''
theta = radians(steering_angle)
return (self.wheeltrack/2) + (self.wheelbase/sin(theta))
def yaw_rate(self, steering_angle, speed):
'''return yaw rate in degrees/second given steering_angle and speed'''
if abs(steering_angle) < 1.0e-6 or abs(speed) < 1.0e-6:
return 0
d = self.turn_circle(steering_angle)
c = pi * d
t = c / speed
rate = 360.0 / t
return rate
def lat_accel(self, steering_angle, speed):
'''return lateral acceleration in m/s/s'''
yaw_rate = self.yaw_rate(steering_angle, speed)
accel = radians(yaw_rate) * speed
return accel
def lat_accel2(self, steering_angle, speed):
'''return lateral acceleration in m/s/s'''
mincircle = self.wheelbase/sin(radians(35))
steer = steering_angle/35
return steer * (speed**2) * (2/mincircle)
def steering_angle(self, lat_accel, speed):
'''return steering angle to achieve the given lat_accel'''
mincircle = self.wheelbase/sin(radians(35))
steer = 0.5 * lat_accel * mincircle / (speed**2)
return steer * 35
def update(self, state):
# if in skid steering mode the steering and throttle values are used for motor1 and motor2
@ -46,7 +84,7 @@ class Rover(Aircraft): @@ -46,7 +84,7 @@ class Rover(Aircraft):
speed = velocity_body.x
# yaw rate in degrees/s
yaw_rate = self.max_turn_rate * steering * (speed / self.max_speed)
yaw_rate = self.yaw_rate(self.max_wheel_turn * steering, speed)
# target speed with current throttle
target_speed = throttle * self.max_speed
@ -90,3 +128,24 @@ class Rover(Aircraft): @@ -90,3 +128,24 @@ class Rover(Aircraft):
# update lat/lon/altitude
self.update_position(delta_time)
if __name__ == "__main__":
r = Rover()
d1 = r.turn_circle(r.max_wheel_turn)
print("turn_circle=", d1)
steer = 0.4*35
speed = 2.65
yrate = r.yaw_rate(steer, speed)
yaccel = r.lat_accel(steer, speed)
yaccel2 = r.lat_accel2(steer, speed)
print yaccel, yaccel2
sangle = r.steering_angle(yaccel, speed)
print steer, sangle
yrate2 = degrees(yaccel / speed)
t = 360.0 / yrate2
c = speed * t
d2 = c / pi
steer2 = degrees(asin(r.wheelbase / (d2 - (r.wheeltrack/2))))
print steer, steer2

Loading…
Cancel
Save