Skip to content

Commit d0c2b74

Browse files
committed
Add example 10 (#112)
1 parent a761126 commit d0c2b74

File tree

3 files changed

+246
-0
lines changed

3 files changed

+246
-0
lines changed

examples/example_10/CMakeLists.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CMAKE_MINIMUM_REQUIRED(VERSION 3.20)
2+
3+
SET(EXECUTABLE example_10)
4+
SET(SOURCE ${EXECUTABLE}.cpp)
5+
6+
ADD_EXECUTABLE(${EXECUTABLE} ${SOURCE})
7+
8+
TARGET_LINK_LIBRARIES(${EXECUTABLE} rlenvscpplib)
9+

examples/example_10/example_10.cpp

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
/*
2+
* In this example we simulate a quadrotor.
3+
* The quadrotor data is taken from
4+
* https://sal.aalto.fi/publications/pdf-files/eluu11_public.pdf
5+
*
6+
*
7+
*
8+
*/
9+
10+
#include "rlenvs/rlenvs_types_v2.h"
11+
#include "rlenvs/dynamics/quadrotor_dynamics.h"
12+
#include "rlenvs/utils/io/csv_file_writer.h"
13+
#include "rlenvs/utils/unit_converter.h"
14+
15+
#include <iostream>
16+
#include <string>
17+
#include <map>
18+
#include <any>
19+
#include <array>
20+
#include <vector>
21+
22+
namespace example_10{
23+
24+
using namespace rlenvscpp::dynamics;
25+
using rlenvscpp::uint_t;
26+
using rlenvscpp::real_t;
27+
using rlenvscpp::RealVec;
28+
using rlenvscpp::utils::io::CSVWriter;
29+
30+
real_t compute_motor_speed(real_t t){
31+
32+
if(t <= 0.1){
33+
return 500 * t + 625.0;
34+
}
35+
else if( t > 0.1 && t <= 0.4){
36+
return -416.66 * t + 716.66;
37+
}
38+
else if( t > 0.4 && t <= 0.5){
39+
return 750.0 * t + 250.0;
40+
}
41+
else{
42+
return 625.0;
43+
}
44+
45+
}
46+
47+
}
48+
49+
50+
int main(){
51+
52+
using namespace example_10;
53+
54+
QuadrotorDynamicsConfig config;
55+
config.dt = 0.0001;
56+
config.mass = 0.468;
57+
config.l = 0.225;
58+
config.k_1 = 2.980e-6; // this is the k coeff
59+
config.k_2 = 1.140e-7; // this is the beta coeff
60+
config.Jx = 4.856e-3;
61+
config.Jy = 4.856e-3;
62+
config.Jz = 8.801e-3;
63+
64+
65+
// initialize the state variables
66+
std::array<std::pair<std::string, real_t>, 12> values;
67+
68+
// initial position in NED
69+
values[0] = std::make_pair("x", 0.0);
70+
values[1] = std::make_pair("y", 0.0);
71+
values[2] = std::make_pair("z", 0.0);
72+
73+
// initial translation velocities body coords
74+
values[3] = std::make_pair("u", 0.0);
75+
values[4] = std::make_pair("v", 0.0);
76+
values[5] = std::make_pair("w", 0.0);
77+
78+
// initial rotational velocities body coords
79+
values[6] = std::make_pair("p", 0.0);
80+
values[7] = std::make_pair("q", 0.0);
81+
values[8] = std::make_pair("r", 0.0);
82+
83+
// Euler angles
84+
values[9] = std::make_pair("phi", 0.0);
85+
values[10] = std::make_pair("theta", 0.0);
86+
values[11] = std::make_pair("psi", 0.0);
87+
88+
89+
SysState<12> state(std::move(values));
90+
QuadrotorDynamics dynamics(config, state);
91+
92+
// the motor velocities rad/sec
93+
RealVec omegas = RealVec::Zero(4);
94+
omegas[0] = omegas[1] = omegas[2] = omegas[3] = 625.0;
95+
96+
97+
CSVWriter csv_writer("state");
98+
csv_writer.open();
99+
100+
std::vector<std::string> names={"t",
101+
"x", "y", "z",
102+
"u", "v", "w",
103+
"p", "q", "r",
104+
"phi", "theta", "psi"};
105+
106+
csv_writer.write_column_names(names);
107+
108+
const real_t T = 2.0;
109+
real_t time = 0.0;
110+
111+
std::vector<real_t> row(13, 0.0);
112+
while(time < T){
113+
114+
std::cout<<"Time: "<<time<<std::endl;
115+
116+
auto omega_motor = compute_motor_speed(time);
117+
omegas[0] = omegas[1] = omegas[2] = omegas[3] = omega_motor;
118+
dynamics.integrate(omegas);
119+
120+
auto p = dynamics.get_position();
121+
auto v = dynamics.get_velocity();
122+
auto omega = dynamics.get_angular_velocity();
123+
auto euler = dynamics.get_euler_angles();
124+
125+
row[0] = time;
126+
row[1] = p[0];
127+
row[2] = p[1];
128+
row[3] = p[2];
129+
130+
row[4] = v[0];
131+
row[5] = v[1];
132+
row[6] = v[2];
133+
134+
row[7] = omega[0];
135+
row[8] = omega[1];
136+
row[9] = omega[2];
137+
138+
row[10] = rlenvscpp::utils::unit_converter::rad_to_degrees(euler[0]);
139+
row[11] = rlenvscpp::utils::unit_converter::rad_to_degrees(euler[1]);
140+
row[12] = rlenvscpp::utils::unit_converter::rad_to_degrees(euler[2]);
141+
142+
csv_writer.write_row(row);
143+
std::cout<<"Current position: ";
144+
std::cout<<p<<std::endl;
145+
std::cout<<euler<<std::endl;
146+
time += config.dt;
147+
}
148+
149+
csv_writer.close();
150+
151+
return 0;
152+
}

examples/example_10/plot.py

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
"""
2+
Utility script for plotting with matplotlib
3+
"""
4+
import matplotlib.pyplot as plt
5+
import csv
6+
import math
7+
import numpy as np
8+
9+
def main(filename):
10+
11+
with open(filename, 'r', newline='') as csvfile:
12+
csv_file_reader = csv.reader(csvfile, delimiter=",")
13+
14+
time = []
15+
x = []
16+
y = []
17+
z = []
18+
u = []
19+
v = []
20+
w = []
21+
p = []
22+
q = []
23+
r = []
24+
phi = []
25+
theta = []
26+
psi = []
27+
28+
for row in csv_file_reader:
29+
if not row[0].startswith('#'):
30+
try:
31+
32+
assert len(row) == 13
33+
34+
time.append(float(row[0]))
35+
x.append(float(row[1]))
36+
y.append(float(row[2]))
37+
z.append(float(row[3]))
38+
39+
u.append(float(row[4]))
40+
v.append(float(row[5]))
41+
w.append(float(row[6]))
42+
43+
p.append(float(row[7]))
44+
q.append(float(row[8]))
45+
r.append(float(row[9]))
46+
47+
phi.append(float(row[10]))
48+
theta.append(float(row[11]))
49+
psi.append(float(row[12]))
50+
except Exception as e:
51+
print(e)
52+
continue
53+
54+
assert len(time) == len(x), "Invalid length"
55+
plt.plot(time, x, label='X^G', linewidth=2)
56+
plt.plot(time, y, label='Y^G', linewidth=2)
57+
plt.plot(time, z, label='Z^G', linewidth=2)
58+
59+
plt.xlabel('time (secs)')
60+
plt.ylabel('position')
61+
plt.title('Quadrotor position in NED')
62+
plt.grid()
63+
plt.legend()
64+
plt.show()
65+
66+
67+
assert len(time) == len(phi), "Invalid length"
68+
69+
plt.plot(time, phi, label='$\phi$', linewidth=2)
70+
plt.plot(time, theta, label='$\theta$', linewidth=2)
71+
plt.plot(time, psi, label='$\psi$', linewidth=2)
72+
plt.xlabel('time (secs)')
73+
plt.ylabel('Angle')
74+
plt.title('Euler angles (deg)')
75+
plt.grid()
76+
plt.legend()
77+
plt.show()
78+
79+
80+
if __name__ == '__main__':
81+
main("/home/alex/qi3/rlenvs_from_cpp/build/examples/example_10/state.csv")
82+
83+
84+
85+

0 commit comments

Comments
 (0)