Reaction Wheel Stabilized Stick
Reaction Wheel Stabilized Stick
BILL LAVEBRATT
PONTUS GRÄSBERG
BILL LAVEBRATT
TRITA-ITM-EX 2019:38
Abstract
Control theory can be used to make an unstable system
stable. This thesis seeks to do this, where the system is a
two DOF inverted pendulum with reaction wheels for sta-
bilisation. The thesis also seeks to answer what is most im-
portant for making it stabilize for a longer period of time.
It was decided that a state space controller was to be used
with various sensors measuring the states. To be able to de-
sign a functioning demonstrator, a mathematical model of
the system dynamics was developed. In the end the demon-
strator proved to function as desired, being able to balance
indefinitely. It was found that it is absolutely necessary to
either give the controller a perfect set point or to implement
an automatic set point.
First of all we would like to thank KTH prototype center and Tomas Östberg for
helping us make the reaction wheels. Also a big thanks to Staffan Qvarnström
for helping us order parts and finding motors for the project as well as to the lab
assistants for helping us and answering various questions.
Contents
Contents
1 Introduction 3
1.1 Background . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.2 Purpose . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.3 Scope . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.4 Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2 Theory 5
2.1 System dynamics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.1.1 Dynamics of the system . . . . . . . . . . . . . . . . . . . . . 5
2.1.2 Motor dynamics . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.1.3 State space model . . . . . . . . . . . . . . . . . . . . . . . . 6
2.2 Control design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.2.1 Simulation and Pole Placement . . . . . . . . . . . . . . . . . 8
2.3 Sensors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.3.1 Accelerometer . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.3.2 Gyroscope . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.3.3 Hall effect sensor . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.4 Kalman filter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.5 Controlling motors . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
4 Results 21
5 Discussion and conclusion 23
5.1 Discussion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
5.2 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
Bibliography 27
Appendices 27
A Datasheets 29
B Schematics 32
C Code 33
C.1 MATLAB code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
C.2 Arduino code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
List of Figures
4.1 Shows the angle and angular velocity of the IMU while stabilising. Made
in MATLAB. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
4.2 Shows how the set point and the angle moved when the center of mass
was changed while stabilizing. Made in MATLAB. . . . . . . . . . . . . 22
Nomenclature
Name Description
m The mass of the structure
I The moment of inertia of the structure
θ Angular diviation from equilibrium point
l Height of the center of mass
Mmotor torque applied by motor
ω Angular velocity of reaction wheel
k2 φ Torque constant of motor
RA Terminal resistance of motor
U Voltage to the motors
θIM U Angle of IMU
dx Set point
T Time period between the updates of PWM signal
L Feedback gain vector
k Gain for automatic set point
1
List of Figures
List of Abbreviations
Abbreviations Description
DOF Degrees of Freedom
IMU Inertial measurement unit
MEMS microelectromechanical systems
PWM Pulse Width Modulation
ODE Ordinary differential equation
RPM Revolutions per minute
2
Chapter 1
Introduction
1.1 Background
The problem of balancing an inverted pendulum is a classical problem in the field
of dynamics and control theory. The problem arises for example when dealing with
rockets or self balancing robots. One method to balance the inverted pendulum is
with reaction wheels.
1.2 Purpose
The Purpose of the project is to use reaction wheels to stabilize an inherently
unstable system. In this case the system is a two DOF inverted pendulum, when
left alone the pendulum will fall. The objective is to keep the pendulum standing.
By using motors to apply torque on the reaction wheels reaction forces will arise
which could keep the pendulum standing. This thesis seeks to answer:
1.3 Scope
Even though the dynamics of the system is nonlinear this thesis only considers linear
control methods. There are several types of controllers that could work, but this
3
CHAPTER 1. INTRODUCTION
thesis investigates only how a state space controller performs. A micro controller
will be used to control the system. The demonstrator shall not be of a height of
more than 0,4 m and shall carry all components needed except the power supply
for the motors.
1.4 Method
First the dynamics of the system was analysed and a mathematical model was
developed. With the mathematical model of the system, simulations were made in
MATLAB. The simulations were used to test various designs and controllers. With
constrains given by the simulations, components were chosen and gathered. The
demonstrator was built and tests were conducted to determine which parameters
are of the most importance to balance the pendulum.
4
Chapter 2
Theory
According to figure 2.1 and Newtons second law, the rotational dynamics of the
pendulum around O can be described as
ez : Ir ω̇ = Mmotor , (2.2)
where Ir is the combined moment of inertia of the reaction wheel and the rotor of
the motor and ω is the angular velocity of the reaction wheel and the motor.
5
CHAPTER 2. THEORY
Knowing that the same equations applies in the yz-plane the model should be
sufficiently accurate for the purpose to stabilize the pendulum.
k2 φ k2 φ2 ω
Mmotor = U− , (2.3)
RA RA
where k2 φ is the torque constant, RA is the terminal resistance and U is the voltage
applied on the motor[1].
6
2.2. CONTROL DESIGN
In this project a state space feedback controller with integral action was chosen
as the controller. Integral action makes the system more robust to modelling errors
and disturbances [2]. A new state variable x4 is introduced to denote the integrator
state which is the integral of the output error. Let r denote the reference or the
wanted output, then the following holds:
7
CHAPTER 2. THEORY
By choosing L, the poles of the system can be placed as desired. Since the system
is asymptotically stable, it will converge to a static state that satisfies r − Cx = 0.
In other words x1 = r. In this case r = 0 since the pendulum shall be balancing
around the equilibrium point where θ = 0.
8
2.3. SENSORS
2.3 Sensors
In order to use a state space controller it is necessary to somehow measure or
estimate the states. In this project the states were measured by using a few different
sensors. The accelerometer and the gyroscope were used to measure the angle and
the angular velocity of the system, and the the Hall effect sensors were used to
measure the angular velocity of the reaction wheels.
2.3.1 Accelerometer
Accelerometers measure the acceleration. To measure the acceleration accelerom-
eters typically use a mass spring system which measures the capacitance. There
might be vibrations in the structure which for the accelerometer in this case are
unwanted noise. The measurement also has a bias which will be constant and can
therefore be mostly removed[3]. The principle of one type of MEMS accelerometer
is shown in figure 2.4.
2.3.2 Gyroscope
A gyroscope measures the angular velocity. It normally does this by having a
spinning disc and using the Coriolis force. A cheaper and often a more practical
9
CHAPTER 2. THEORY
10
2.5. CONTROLLING MOTORS
11
Chapter 3
This chapter describes the design of the demonstrator, the relevant hardware that
was used and the reasoning behind them. It also considers the software implementa-
tion. The simulation model in MATLAB with data from the CAD model indicated
how the demonstrator should be designed to function as desired. Due to cost limi-
tations and components available our ideal design could not be achieved and some
compromises had to be made.
3.1 Motors
Simulations were done in order to find approximate requirements for the motors.
The system performance is largely dependent on its mass and the power that the
motors can deliver, and since the power a motor can deliver is proportional to its
mass, there was no easy way to calculate the exact requirements on the specifications
of the motors. Here the mathematical model of the system dynamics that was built
was crucial. It made it possible to simulate the system behaviour with various
parameter values. A motor with high power to weight ratio could improve the
system performance. It was estimated that a motor that can deliver around 0,2
Nm of torque and with the mass of about 0,4 kg could stabilize the system. One
of the motors available with similar specifications was a motor manufactured by
Dunkermotoren of model GR 42x40. The mass of this model is 0,49 kg and it
can deliver 0,33 Nm during stall torque. It was found in the simulations that the
pendulum should be able to balance using this motor. The data sheet for the GR
42x40 motor can be seen in appendix A, figure A.1.
13
CHAPTER 3. DESIGN AND IMPLEMENTATION
these conditions the H-bridge Pololu Dual VNH5019 Motor Driver was chosen. This
H-bridge can operate at 24 V and deliver a continuous current of 12 A per channel,
which is sufficient for the purpose. The VNH5019 also features PWM operation up
to 20 kHz which enables quieter and smoother running of the motors[8]. General
specifications for the H-bridge taken from the Pololu website can be seen in appendix
A figure A.2.
When sensor 1 detects a magnet the system checks if sensor 2 is detecting a magnet.
If so, the magnets are moving to the right, otherwise the magnets are moving to
the left. By counting detections and measuring the time difference between the
detections the angular velocity can be calculated.
Figure 3.2. Plot of measured angular velocity of reaction wheel. Made in MATLAB.
14
3.3. INERTIAL MEASUREMENT UNIT
Figure 3.2 shows the measured angular velocity of one of the reaction wheels where
the motor was given 24 volts for seven seconds, -24 volts for seven seconds and then
zero volts until the angular velocity became zero.
Figure 3.3. The angle as given by the accelerometer, gyroscope and Kalman filter.
Made in MATLAB.
Figure 3.3 shows the angle as given by the accelerometer, gyroscope and Kalman
filter. It can be seen that the accelerometer had a lot of noise and that the gyroscope
drifted with time as stated in section 2.3. The Kalman filtered data has low noise
and is not time delayed as some filters can cause, making it suitable for use in the
controller. Note that figure 3.3 shows two 90◦ turns of the system. In reality the
the demonstrator will only move a few degrees making the value given directly by
the accelerometer useless because of the noise to signal ratio.
3.4 Construction
It was decided that a platform to hold the components and the stick together would
be 3D-printed. The aim of the platform was to get the system as compact as possi-
ble and the weight close to the stick to get the center of mass approximately above
it. It was also of importance to fasten the motors to reduce vibrations caused by
15
CHAPTER 3. DESIGN AND IMPLEMENTATION
them. The design also features an adjustable height of the platform since there was
uncertainties about which height that would work. The stick chosen was a beam of
steel with a radius of 2 mm.
The reaction wheels were designed to have low mass while simultaneously keeping a
high moment of inertia. They were designed in Solid Edge and then manufactured
by using a water cutter to cut out the silhouette out of a sheet of steel, and then
milling material away from the inner parts to lower the mass while keeping a high
moment of inertia. The whole structure was then put together with screws and set
screw hubs as shown in figure 3.4 where the CAD model is seen. All of the electrical
components were also put on the platform and connected as the schematics figure
B.1 illustrates. Figure 3.5 shows the finished demonstrator while balancing. Here
the lower side of the platform is placed on a height of 10 cm and the diameter of
the reaction wheels is 15 cm.
16
3.5. CODE
3.5 Code
An Arduino Uno was used as the controller unit due to its ease of use and in-
expensiveness. The code was written in Arduinos IDE and then uploaded to the
Arduino Uno. A simplification of the logical flow of the program is illustrated in the
flowchart in figure 3.6. In the main loop the data from the IMU is updated every
iteration, while the angular velocity of the reaction wheel is only recalculated and
updated when the hall sensors have detected more than three magnets going in the
same direction. This means the calculated angular velocity is the mean value of the
angular velocity during the last three detections whenever the angular velocity is
updated. Accordingly there are delays in this data and it could be more precise by
adding more magnets.
The PWM signal is updated when the time T has elapsed since the last time the
PWM signal was updated. When the PWM signal is updated a function is called
that takes the states as input and returns the voltage that should be sent to the
motor. The function basically uses equation 2.10 (u = −Lx) to calculate the volt-
age, but with the restriction of setting the voltage to 24 V if equation 2.10 gives a
voltage that exceeds 24 V. It also integrates the error to form the integrator state
as according to equation 2.9. Though if the voltage exceeds 24 V the input signal is
saturated and no integration is done. This is refereed to as an anti windup method
and it keeps the integrator from growing when the actuator is saturated and can not
17
CHAPTER 3. DESIGN AND IMPLEMENTATION
produce the wanted output. Anti windup prevents large overshoot and oscillations
in the output signal of the system [10].
18
3.6. TUNING OF THE CONTROLLER
aligned to the line of center of mass, the data has to be compensated for this. This
is done by subtracting a small angle dx to the angle read by the IMU θIM U before
it goes into the controller. This means the controller will try to get θIM U = dx, and
therefore dx can be interpreted as the set point. dx compensates for the slanting
IMU and the center of mass not being precisely above the stick. If this compensation
is not exactly correct the stabilisation will fail after a short time. The system
will try to regulate itself to a state where the center of mass is not above the
interface between the ground and the stick. This will result in a small torque
constantly pulling in one direction and the reaction wheels will constantly have to
accelerate to keep up for this. The motors will build up speed until they can no
longer apply any torque. This problem can be solved by changing dx over time as
dxn −θIM U
dxn+1 = dxn + k |dx n −θIM U |
, where k is some positive gain. This means dx or the set
point will increase if dx > θIM U and decrease if dx < θIM U . If k is chosen so that
the set point change a bit slower than θIM U it solves the problem of not knowing
the correct set point. The set point will automatically go towards a good value. See
figure 3.7 where the stabilisation starts at time=0.
Figure 3.7. Shows how the set point moves compered to the angle while stabilising.
Made in MATLAB.
A mathematical proof for that this should work could not be found. But there are
some similar work where similar solutions were briefly discussed [11].
19
Chapter 4
Results
When implementing the state space controller on its own the system never seemed
to be able to balance over time. The pendulum could stand up for a while but
always fell after tens of seconds or at best after some minutes. We strongly suspect
that the problem was because of the set point, which is discussed in chapter 3.6.
After the implementation of the automatic set point, the system became seemingly
stable. There was no sign that the system could not balance indefinitely when no
disturbances were applied. Figure 4.1 shows the angle and angular velocity of the
IMU while stabilising.
Figure 4.1. Shows the angle and angular velocity of the IMU while stabilising.
Made in MATLAB.
The demonstrator could handle disturbances such as someone pushing slightly on its
platform. Also the automatic set point made the system able to handle changes to
the center of mass while balancing. Figure 4.2 shows the behaviour when a mass is
put near one of the platforms edges. It illustrates how the system automatically finds
the new angle it should stabilize around. In the end L = [−550 −60 −0, 0585 1000],
k = 0, 00003 and T = 0, 001 seconds were considered to give the best performance.
This is while the platform was placed on a height of 10 cm. Large vibrations started
21
CHAPTER 4. RESULTS
Figure 4.2. Shows how the set point and the angle moved when the center of mass
was changed while stabilizing. Made in MATLAB.
22
Chapter 5
5.1 Discussion
In order to acquire data to make the graphs in this report the arduino had to send
data to the computer. Since the arduino did not have wireless transmission built in
nor was this added, this data transfer went through a cable. Because of the rather
thick cable the system was not optimal when collecting data. The cable caused dis-
turbances by pulling on the system. This was however not the greatest disturbance
to the system while sending data. When the Arduino sent data there were delays
causing the code to slow down. This made the system more unstable and caused
an increased swaying movement that can be seen in figure 3.7, 4.1 and 4.2. To deal
with this effect data was sent less often to the computer. It made the system more
stable but reduced the resolution of the data shown in figure 3.7, 4.1 and 4.2.
The height of the platform proved to be an important factor to make the sys-
tem stable. This was predicted with the mathematical model of the system. What
was not as anticipated were the large vibrations that occurred when the the height
of the platform was increased. The objective was to put the platform a bit higher,
but it turned out that the vibrations made this very difficult. Apart from the stick
being to weak, the reaction wheels were not perfectly symmetrical and this might
have caused unnecessary excitement to the stick making it vibrate.
The first feedback gain L that was implemented in the micro controller was accord-
ing to the simulations enough to make the system stable. It was then discovered
that an L that was predicted to give a much faster system was superior. This was
probably due to the delays that occurred in the real system that had not been ac-
counted for in the simulations. Also the mathematical model was an approximation
and was not expected to describe the system perfectly.
23
CHAPTER 5. DISCUSSION AND CONCLUSION
5.2 Conclusion
Several parameters such as the mass, the height of the center of mass and the
moment of inertia of the reaction wheels are of importance to get the system stable.
As expected it is important to implement a good controller and especially a correct
set point so that the system does not try to stabilize towards a wrong angle. While
methods for finding a good set point can be developed, the system is still very
sensitive to changes in the center of mass and may still fail to balance after some
time. In order to make the system stable over time an automatic set point was
implemented as described in 3.6.1, which makes the system stable indefinitely.
24
Chapter 6
6.1 Recommendations
Even if the demonstrator worked it had some flaws and there are room for im-
provements. There were resonance frequencies in the system when the height of
the platform was increased. For future work it would be of importance to use a
stiffer stick for the demonstrator. It would also be recommended to use reaction
wheels that are symmetrical as to not cause any vibrations. Finally it would be rec-
ommended to use a rotary encoder to measure the angular velocity of the reaction
wheels with higher precision.
25
Bibliography
27
Appendix A
Datasheets
29
APPENDIX A. DATASHEETS
30
31
APPENDIX B. SCHEMATICS
Appendix B
Schematics
Code
33
statespace_motor_integrator.m
% Project name: Reaction Wheel Stabilized Stick
% Bachelor thesis in mechatronics at KTH, spring 2019
% Bill Lavebratt, Pontus Gräsberg
% Description of code:
% Matlab program for simulation of the system. Needs the function
RK4systk.m
% It predicts how the system will behave when implementing a State
space
% controller
C=[1 0 0];
1
Umax=24; % Maximum voltage
figure
plot(tv,yv(:,2))
grid on, title('Angular velocity of pendulum'), xlabel('t [s]'),
ylabel('rad/s');
figure
plot(tv,yv(:,4))
grid on, title('Integral(ref-angle)'), xlabel('t [s]');
figure
plot(tv,yv(:,3))
grid on, title('Angular velocity of reaction wheel'), xlabel('t [s]'),
ylabel('rad/s');
U(ii)=Umax*U(ii)/abs(U(ii));
end
end
figure
plot(tv,U)
grid on, title('Voltage'), xlabel('t [s]'), ylabel('V');
figure
plot(tv,Mmotor)
grid on, title('Torque from motor'), xlabel('t [s]'), ylabel('Nm');
2
RK4systk.m
% Project name: Reaction Wheel Stabilized Stick
% Bachelor thesis in mechatronics at KTH, spring 2019
% Bill Lavebratt, Pontus Gräsberg
% Description of code:
% Matlab function for simulation of the system.
% Implementation of a Runge-Kutta 4th Order method for System of
differential equations.
% The input is f: function of system of differential equations, tspan:
% start time and end time of simulation, y0: Initial conditions, h:
% steplength.
% The output is tv: the time vector, yv: matrix of the solution to the
% system of differential equations.
function [tv,yv]=RK4systk(f,tspan,y0,h)
n=(tspan(2)-tspan(1))/h;
tv=(tspan(1)+h*(0:n))';
p=length(y0);
yv=zeros(n+1,p);
yv(1,:)=y0;
for ii=1:n
k1=feval(f,tv(ii),yv(ii,:));
k2=feval(f,tv(ii)+h/2,yv(ii,:)+h/2*k1);
k3=feval(f,tv(ii)+h/2,yv(ii,:)+h/2*k2);
k4=feval(f,tv(ii)+h,yv(ii,:)+h*k3);
yv(ii+1,:)=yv(ii,:)+h/6*(k1+2*k2+2*k3+k4);
end
end
1
C.2. ARDUINO CODE
/∗
∗ University : Royal I n s t i t u t e o f Technology , KTH
∗ TRITA number : TRITA−ITM−EX 2 0 1 9 : 3 8
∗ Authors : B i l l L a v e b r a t t and Pontus G r s b e r g
∗ Name o f p r o j e c t : R e a c t i o n wheel s t a b a l i z e d s t i c k
∗
∗ D e s c r i p t i o n o f code :
∗ Main program used t o b a l a n c e t h e r e a c t i o n wheel s t a b a l i z e d s t i c k .
∗ F i l t e r e d s t a t e measurements g o e s i n t o a c o n t r o l e r / r e g u l a t o r f u n c t i o n
t h a t c a l c u l a t e s t h e d e s i r e d v o l t a g e t o t h e motors .
∗ Then t h e c o r e s p o n d i n g PWM s i g n a l s i s s e n t t o an H−b r i d g e .
∗/
#i n c l u d e <Wire . h>
#i n c l u d e <Kalman . h> // S o u r c e : h t t p s : / / g i t h u b . com/ T K J E l e c t r o n i c s /
KalmanFilter
f l o a t BY2 ; // C r e a t e v a r i b l e f o r Butterworth f i l t e r o f g y r o r a t e
f l o a t BX2 ;
int i ;
int i i ;
f l o a t dx1 ;
f l o a t dy1 ;
const f l o a t cutoff_freq = 5 . 0 ; // C u t o f f f r e q u e n c y i n Hz f o r
Butterworth f i l t e r
c o n s t f l o a t sampling_time = 0 . 0 0 5 5 ; // Sampling time i n s e c o n d s .
IIR : : ORDER o r d e r = IIR : : ORDER : : OD3 ; // Order (OD1 t o OD4)
// Low−p a s s f i l t e r
F i l t e r f ( c u t o f f _ f r e q , sampling_time , o r d e r ) ; // Function f o r Butterworth
filter
F i l t e r g ( c u t o f f _ f r e q , sampling_time , o r d e r ) ;
f l o a t g y r o X r a t e 3 ; // V a r i b l e f o r g y r o r a t e g i v e n by MPU
f l o a t gyroYrate3 ;
37
APPENDIX C. CODE
f l o a t dx = 0 . 0 3 ; // S t a r t i n g s e t p o i n t
f l o a t dy = 0 . 0 0 6 ;
/∗ IMU Data ∗/
d o u b l e accX , accY , accZ ;
d o u b l e gyroX , gyroY , gyroZ ;
i n t 1 6 _ t tempRaw ;
uint32_t timer ;
u i n t 8 _ t i 2 c D a t a [ 1 4 ] ; // B u f f e r f o r I2C data
// V a r i b l e s f o c o n t r o l l e r
f l o a t L1=−550; // S t a t e s p a c e f e e d b a c k g a i n
f l o a t L2=−60;
f l o a t L3= −0.0585;
f l o a t L4 =1000;
f l o a t v_ref =0;
f l o a t DT= 0 . 0 0 1 ; //Time p e r i o d between t h e u p d a t e s o f PWM s i g n a l (
Helpful f o r i n t e g r a t o r part )
u n s i g n e d l o n g oldTime =0;
// S t a t e v a r i a b l e s f o r d i r e c t i o n 1
f l o a t v_vink1 ;
f l o a t v_hast1 ;
f l o a t radps1 ;
f l o a t x41 =0;
// S t a t e v a r i a b l e s f o r d i r e c t i o n 2
f l o a t v_vink2 ;
f l o a t v_hast2 ;
f l o a t radps2 ;
f l o a t x42 =0;
// v a r i b l e f o r c o n t r o l l e r
f l o a t Umax=24; // Maximum v o l t a g e
f l o a t U1 ;
f l o a t U2 ;
// P i n s f o r H−b r i d g e
#d e f i n e M1PWM 9
#d e f i n e M1INA 13
#d e f i n e M1INB 12
#d e f i n e M1CS A0
i n t M1EN = 1 1 ;
#d e f i n e M2PWM 10
#d e f i n e M2INA 8
#d e f i n e M2INB 7
38
C.2. ARDUINO CODE
i n t M2EN = 4 ;
i n t 3 2 _ t f r e q =20000; //PWM f r e q
f l o a t pwmOutput1=0; // PWM s i g n a l v a r i b l e s
f l o a t pwmOutput2=0;
// V a r i a b l e s f o r H a l l s e n s o r
u n s i g n e d l o n g DTH1;
u n s i g n e d l o n g DTH2;
unsigned long timeold1 ;
unsigned long timeold2 ;
i n t i n t e r r u p t P i n 1 1 =2;
i n t i n t e r r u p t P i n 2 1 =3;
i n t drPin12=A0 ;
i n t drPin22=A1 ;
void setup ( ) {
InitTimersSafe () ;
S e t P i n F r e q u e n c y S a f e (M1PWM, f r e q ) ;
// For motor
pinMode (M1PWM, OUTPUT) ;
pinMode (M1INA, OUTPUT) ;
pinMode (M1INB, OUTPUT) ;
pinMode (M1EN, OUTPUT) ;
pinMode (M2PWM, OUTPUT) ;
pinMode (M2INA, OUTPUT) ;
pinMode (M2INB, OUTPUT) ;
pinMode (M2EN, OUTPUT) ;
// S e t i n i t i a l r o t a t i o n d i r e c t i o n
d i g i t a l W r i t e (M1INA, HIGH) ;
d i g i t a l W r i t e (M1INB, LOW) ;
d i g i t a l W r i t e (M1EN, HIGH) ;
d i g i t a l W r i t e (M2INA, HIGH) ;
d i g i t a l W r i t e (M2INB, LOW) ;
d i g i t a l W r i t e (M2EN, HIGH) ;
// For H a l l s e n s o r
// I n i t i a l i z e t h e i n t t e r r u p t p i n ( Arduino d i g i t a l p i n 2 )
attachInterrupt ( digitalPinToInterrupt ( interruptPin11 ) ,
magnet_detect1 , FALLING) ;
// I n i t i a l i z e t h e i n t t e r r u p t p i n ( Arduino d i g i t a l p i n 3 )
attachInterrupt ( digitalPinToInterrupt ( interruptPin21 ) ,
magnet_detect2 , FALLING) ;
pinMode ( drPin12 , INPUT) ;
pinMode ( drPin22 , INPUT) ;
39
APPENDIX C. CODE
S e r i a l . begin (115200) ;
Wire . b e g i n ( ) ;
#i f ARDUINO >= 157
Wire . s e t C l o c k ( 4 0 0 0 0 0UL) ; // S e t I2C f r e q u e n c y t o 400kHz
#e l s e
TWBR = ( (F_CPU / 400000UL) − 1 6 ) / 2 ; // S e t I2C f r e q u e n c y t o 400
kHz
#e n d i f
d e l a y ( 1 0 0 ) ; // Wait f o r s e n s o r t o s t a b i l i z e
kalmanX . s e t A n g l e ( r o l l ) ; // S e t s t a r t i n g a n g l e
kalmanY . s e t A n g l e ( p i t c h ) ;
gyroXangle = r o l l ;
gyroYangle = p i t c h ;
40
C.2. ARDUINO CODE
timer = micros ( ) ;
//MAIN LOOP
void loop ( ) {
// C a l c u l a t e s a n g u l a r v e l o c i t y [ rad / s ] f o r H a l l e f f e c t s e n s o r s
i f ( abs ( h a l f _ r e v o l u t i o n s 1 ) >3) {
DTH1 = ( m i c r o s ( ) − t i m e o l d 1 ) ;
r a d p s 1 = −3.1416∗1000000∗( h a l f _ r e v o l u t i o n s 1 /DTH1) / 2 . 0 ;
half_revolutions1 = 0;
timeold1 = micros () ;
}
i f ( abs ( h a l f _ r e v o l u t i o n s 2 ) >3) {
DTH2 = ( m i c r o s ( ) − t i m e o l d 2 ) ;
r a d p s 2 = −3.1416∗1000000∗( h a l f _ r e v o l u t i o n s 2 /DTH2) / 2 . 0 ;
half_revolutions2 = 0;
timeold2 = micros () ;
// C a l c u l a t e new v o l t a g e with t h e c o n t r o l l e r / r e g u l a t o r f u n c t i o n t h a t
t a k e s t h e s t a t e s and r e t u r n s t h e d e s i r e d v o l t a g e .
U1=r e g u l a t o r ( v_vink1 , v_hast1 , radps1 ,& x41 ) ; // V o l t a g e f o r motor1
U2=r e g u l a t o r ( v_vink2 , v_hast2 , radps2 ,& x42 ) ; // V o l t a g e f o r motor2
oldTime=m i c r o s ( ) ;
// Sens d e s i r e d v o l t a g e t o f u n c t i o n s t h a t s e t s t h e PWM s i g n a l
corresponding to the d e s i r e d vol tage
motor1pwm (U1) ;
41
APPENDIX C. CODE
motor2pwm (U2) ;
}
}
//FUNKCTIONS BELOW
// R e g u l a t o r f u n c t i o n t h a t t a k e s t h e s t a t e s and r e t u r n s t h e v o l t a g e
f l o a t r e g u l a t o r ( f l o a t v_vink , f l o a t v_hast , f l o a t s_hast , f l o a t ∗ x4 ) {
f l o a t temp=∗x4 ;
( ∗ x4 ) =(∗x4 ) +(v_ref−v_vink ) ∗DT; // i n t e g r a t o r p a r t o f c o n t r o l l e r
f l o a t UU;
r e t u r n UU;
}
// Function t h a t s e t s t h e PWM s i g n a l c o r r e s p o n d i n g t o t h e d e s i r e d
voltage
v o i d motor2pwm ( f l o a t s p a n n i n g 1 ) {
// Function t h a t s e t s t h e PWM s i g n a l c o r r e s p o n d i n g t o t h e d e s i r e d
voltage
v o i d motor1pwm ( f l o a t s p a n n i n g 2 ) {
42
C.2. ARDUINO CODE
else{
d i g i t a l W r i t e (M2INA, LOW) ;
d i g i t a l W r i t e (M2INB, HIGH) ;
d i g i t a l W r i t e (M2EN, HIGH) ;
s p a n n i n g 2=abs ( s p a n n i n g 2 ) ;
}
pwmOutput2 = map( spanning2 , 0 , Umax, 0 , 2 5 5 ) ; // Map t h e
p o t e n t i o m e t e r v a l u e from 0 t o 255
pwmWrite (M2PWM, pwmOutput2 ) ;
}
d o u b l e dt = ( d o u b l e ) ( m i c r o s ( ) − t i m e r ) / 1 0 0 0 0 0 0 ; // C a l c u l a t e d e l t a
time
timer = micros ( ) ;
43
APPENDIX C. CODE
// atan2 o u t p u t s t h e v a l u e o f − to ( r a d i a n s ) − s e e h t t p : / / en .
w i k i p e d i a . o r g / w i k i / Atan2
// I t i s then c o n v e r t e d from r a d i a n s t o d e g r e e s
#i f d e f RESTRICT_PITCH // Eq . 25 and 26
d o u b l e r o l l = atan2 ( accY , accZ ) ∗ RAD_TO_DEG;
d o u b l e p i t c h = atan (−accX / s q r t ( accY ∗ accY + accZ ∗ accZ ) ) ∗
RAD_TO_DEG;
#e l s e // Eq . 28 and 29
d o u b l e r o l l = atan ( accY / s q r t ( accX ∗ accX + accZ ∗ accZ ) ) ∗
RAD_TO_DEG;
d o u b l e p i t c h = atan2 (−accX , accZ ) ∗ RAD_TO_DEG;
#e n d i f
#i f d e f RESTRICT_PITCH
// This f i x e s t h e t r a n s i t i o n problem when t h e a c c e l e r o m e t e r a n g l e
jumps between −180 and 180 d e g r e e s
i f ( ( r o l l < −90 && kalAngleX > 9 0 ) | | ( r o l l > 90 && kalAngleX < −90) )
{
kalmanX . s e t A n g l e ( r o l l ) ;
kalAngleX = r o l l ;
gyroXangle = r o l l ;
} else
kalAngleX = kalmanX . g e t A n g l e ( r o l l , gyroXrate , dt ) ; // C a l c u l a t e t h e
a n g l e u s i n g a Kalman f i l t e r
44
C.2. ARDUINO CODE
g y r o X r a t e 3 = kalmanX . g e t R a t e ( ) ; // C a l c u l a t e gyro a n g l e u s i n g t h e
unbiased rate
g y r o Y r a t e 3 = kalmanY . g e t R a t e ( ) ;
v_hast1 = 3 . 1 4 1 5 / 1 8 0 . 0 ∗BX2 ;
v_hast2 = 3 . 1 4 1 5 / 1 8 0 . 0 ∗BY2 ;
Contact i n f o r m a t i o n
−−−−−−−−−−−−−−−−−−−
K r i s t i a n Lauszus , TKJ E l e c t r o n i c s
Web : h t t p : / /www. t k j e l e c t r o n i c s . com
e−m a i l : k r i s t i a n l @ t k j e l e c t r o n i c s . com
∗/
u i n t 8 _ t i 2 c W r i t e ( u i nt 8 _t r e g i s t e r A d d r e s s , u i nt 8 _t data , b o o l sendStop )
{
45
APPENDIX C. CODE
u i n t 8 _ t i 2 c W r i t e ( u i nt 8 _t r e g i s t e r A d d r e s s , u i nt 8 _t ∗ data , ui n t8 _t l e n g t h
, b o o l sendStop ) {
Wire . b e g i n T r a n s m i s s i o n ( IMUAddress ) ;
Wire . w r i t e ( r e g i s t e r A d d r e s s ) ;
Wire . w r i t e ( data , l e n g t h ) ;
u i n t 8_ t r c o d e = Wire . e n d T r a n s m i s s i o n ( sendStop ) ; // Returns 0 on
success
i f ( rcode ) {
S e r i a l . p r i n t (F( " i 2 c W r i t e f a i l e d : " ) ) ;
S e r i a l . p r i n t l n ( rcode ) ;
}
r e t u r n r c o d e ; // See : h t t p : / / a r d u i n o . c c / en / R e f e r e n c e /
WireEndTransmission
}
u i n t 8 _ t i2cRead ( ui n t8 _ t r e g i s t e r A d d r e s s , ui n t8 _ t ∗ data , ui n t8 _t n b y t e s )
{
u i n t3 2 _ t timeOutTimer ;
Wire . b e g i n T r a n s m i s s i o n ( IMUAddress ) ;
Wire . w r i t e ( r e g i s t e r A d d r e s s ) ;
u i n t 8_ t r c o d e = Wire . e n d T r a n s m i s s i o n ( f a l s e ) ; // Don ’ t r e l e a s e t h e bus
i f ( rcode ) {
S e r i a l . p r i n t (F( " i2cRead f a i l e d : " ) ) ;
S e r i a l . p r i n t l n ( rcode ) ;
r e t u r n r c o d e ; // See : h t t p : / / a r d u i n o . c c / en / R e f e r e n c e /
WireEndTransmission
}
Wire . requestFrom ( IMUAddress , nbytes , ( u in t 8_ t ) t r u e ) ; // Send a
r e p e a t e d s t a r t and then r e l e a s e t h e bus a f t e r r e a d i n g
f o r ( u i nt 8 _t i = 0 ; i < n b y t e s ; i ++) {
i f ( Wire . a v a i l a b l e ( ) )
data [ i ] = Wire . r e a d ( ) ;
else {
timeOutTimer = m i c r o s ( ) ;
w h i l e ( ( ( m i c r o s ( ) − timeOutTimer ) < I2C_TIMEOUT) && ! Wire .
available () ) ;
i f ( Wire . a v a i l a b l e ( ) )
data [ i ] = Wire . r e a d ( ) ;
else {
S e r i a l . p r i n t l n (F( " i2cRead t i m e o u t " ) ) ;
r e t u r n 5 ; // This e r r o r v a l u e i s not a l r e a d y taken by
endTransmission
}
}
}
r e t u r n 0 ; // S u c c e s s
}
46
TRITA TRITA-ITM-EX 2019:38
www.kth.se