APM:Libraries
SIM_Rover.cpp
Go to the documentation of this file.
1 /*
2  This program is free software: you can redistribute it and/or modify
3  it under the terms of the GNU General Public License as published by
4  the Free Software Foundation, either version 3 of the License, or
5  (at your option) any later version.
6 
7  This program is distributed in the hope that it will be useful,
8  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  GNU General Public License for more details.
11 
12  You should have received a copy of the GNU General Public License
13  along with this program. If not, see <http://www.gnu.org/licenses/>.
14  */
15 /*
16  rover simulator class
17 */
18 
19 #include "SIM_Rover.h"
20 
21 #include <string.h>
22 #include <stdio.h>
23 
24 namespace SITL {
25 
26 SimRover::SimRover(const char *home_str, const char *frame_str) :
27  Aircraft(home_str, frame_str),
28  max_speed(20),
29  max_accel(10),
30  max_wheel_turn(35),
31  turning_circle(1.8),
32  skid_turn_rate(140), // degrees/sec
33  skid_steering(false)
34 {
35  skid_steering = strstr(frame_str, "skid") != nullptr;
36 
37  if (skid_steering) {
38  printf("SKID Steering Rover Simulation Started\n");
39  // these are taken from a 6V wild thumper with skid steering,
40  // with a sabertooth controller
41  max_accel = 14;
42  max_speed = 4;
43  }
44 }
45 
46 
47 
48 /*
49  return turning circle (diameter) in meters for steering angle proportion in degrees
50 */
51 float SimRover::turn_circle(float steering)
52 {
53  if (fabsf(steering) < 1.0e-6) {
54  return 0;
55  }
56  return turning_circle * sinf(radians(max_wheel_turn)) / sinf(radians(steering*max_wheel_turn));
57 }
58 
59 /*
60  return yaw rate in degrees/second given steering_angle and speed
61 */
62 float SimRover::calc_yaw_rate(float steering, float speed)
63 {
64  if (skid_steering) {
65  return steering * skid_turn_rate;
66  }
67  if (fabsf(steering) < 1.0e-6 or fabsf(speed) < 1.0e-6) {
68  return 0;
69  }
70  float d = turn_circle(steering);
71  float c = M_PI * d;
72  float t = c / speed;
73  float rate = 360.0f / t;
74  return rate;
75 }
76 
77 /*
78  return lateral acceleration in m/s/s
79 */
80 float SimRover::calc_lat_accel(float steering_angle, float speed)
81 {
82  float yaw_rate = calc_yaw_rate(steering_angle, speed);
83  float accel = radians(yaw_rate) * speed;
84  return accel;
85 }
86 
87 /*
88  update the rover simulation by one time step
89  */
90 void SimRover::update(const struct sitl_input &input)
91 {
92  float steering, throttle;
93 
94  // if in skid steering mode the steering and throttle values are used for motor1 and motor2
95  if (skid_steering) {
96  float motor1 = 2*((input.servos[0]-1000)/1000.0f - 0.5f);
97  float motor2 = 2*((input.servos[2]-1000)/1000.0f - 0.5f);
98  steering = motor1 - motor2;
99  throttle = 0.5*(motor1 + motor2);
100  } else {
101  steering = 2*((input.servos[0]-1000)/1000.0f - 0.5f);
102  throttle = 2*((input.servos[2]-1000)/1000.0f - 0.5f);
103  }
104 
105  // how much time has passed?
106  float delta_time = frame_time_us * 1.0e-6f;
107 
108  // speed in m/s in body frame
109  Vector3f velocity_body = dcm.transposed() * velocity_ef;
110 
111  // speed along x axis, +ve is forward
112  float speed = velocity_body.x;
113 
114  // yaw rate in degrees/s
115  float yaw_rate = calc_yaw_rate(steering, speed);
116 
117  // target speed with current throttle
118  float target_speed = throttle * max_speed;
119 
120  // linear acceleration in m/s/s - very crude model
121  float accel = max_accel * (target_speed - speed) / max_speed;
122 
123  gyro = Vector3f(0,0,radians(yaw_rate));
124 
125  // update attitude
126  dcm.rotate(gyro * delta_time);
127  dcm.normalize();
128 
129  // accel in body frame due to motor
130  accel_body = Vector3f(accel, 0, 0);
131 
132  // add in accel due to direction change
133  accel_body.y += radians(yaw_rate) * speed;
134 
135  // now in earth frame
136  Vector3f accel_earth = dcm * accel_body;
137  accel_earth += Vector3f(0, 0, GRAVITY_MSS);
138 
139  // we are on the ground, so our vertical accel is zero
140  accel_earth.z = 0;
141 
142  // work out acceleration as seen by the accelerometers. It sees the kinematic
143  // acceleration (ie. real movement), plus gravity
144  accel_body = dcm.transposed() * (accel_earth + Vector3f(0, 0, -GRAVITY_MSS));
145 
146  // new velocity vector
147  velocity_ef += accel_earth * delta_time;
148 
149  // new position vector
150  position += velocity_ef * delta_time;
151 
152  // update lat/lon/altitude
153  update_position();
154  time_advance();
155 
156  // update magnetic field
158 }
159 
160 } // namespace SITL
Vector3f accel_body
Definition: SIM_Aircraft.h:142
int printf(const char *fmt,...)
Definition: stdio.c:113
Vector3f position
Definition: SIM_Aircraft.h:140
float calc_yaw_rate(float steering, float speed)
Definition: SIM_Rover.cpp:62
Vector3< float > Vector3f
Definition: vector3.h:246
float max_wheel_turn
Definition: SIM_Rover.h:43
SimRover(const char *home_str, const char *frame_str)
Definition: SIM_Rover.cpp:26
float max_accel
Definition: SIM_Rover.h:42
float turning_circle
Definition: SIM_Rover.h:44
bool skid_steering
Definition: SIM_Rover.h:46
float calc_lat_accel(float steering_angle, float speed)
Definition: SIM_Rover.cpp:80
float turn_circle(float steering)
Definition: SIM_Rover.cpp:51
Matrix3< T > transposed(void) const
Definition: matrix3.cpp:189
#define GRAVITY_MSS
Definition: definitions.h:47
#define f(i)
Vector3f velocity_ef
Definition: SIM_Aircraft.h:136
T y
Definition: vector3.h:67
T z
Definition: vector3.h:67
void update_mag_field_bf(void)
uint64_t frame_time_us
Definition: SIM_Aircraft.h:167
void update_position(void)
static constexpr float radians(float deg)
Definition: AP_Math.h:158
void rotate(const Vector3< T > &g)
Definition: matrix3.cpp:115
float max_speed
Definition: SIM_Rover.h:41
#define M_PI
Definition: definitions.h:10
void normalize(void)
Definition: matrix3.cpp:135
float skid_turn_rate
Definition: SIM_Rover.h:45
T x
Definition: vector3.h:67
void update(const struct sitl_input &input)
Definition: SIM_Rover.cpp:90