Vous êtes sur la page 1sur 27

Simulating and Implementing Speed Control for an Electric Motorcycle

Lennon Rodgers, Eric Gilbertson, Kavya Manyapu



Massachusetts Institute of Technology
Department of Mechanical Engineering
2.140 Analysis and Design of Feedback Control
Final Project for Spring 2009
1. IntroductionandOverview
This study simulates and implements closed-loop PID speed control on an electric motorcycle.
Firstly, a theoretical model of the plant (motorcycle) was formulated using the derived equations of
motion and the Single Input Single Output (SISO) techniques learn in this course. A PID controller was
chosen because the Proportional controller (P) has good disturbance rejection properties, the Integral
controller (I) provides zero steady state error to a step input and the Derivative controller (D) leads to a
faster response. The SISO tool in Matlab was initially used to obtain estimates for the gains of the
controller required to meet a rise time of ~4 seconds, and zero steady state error requirements. The plant
and controller model were then simulated using Simulink and the gains were tuned appropriately to obtain
precise specifications. Furthermore, performing driving experiments with the electric motorcycle
validated the model. The simulation and experiments were performed under various disturbances, such as
hills and wind.
2. SystemModel
A model of the Plant (motorcycle) was first determined. To accomplish this, the equations of
motion were derived.
2.1. EquationsofMotionforthePlant
The motorcycle can be simplified as a mass on an incline with externally applied forces acting on
it (Figure 2-1). The motorcycle is propelled forward by a force on the wheel, F
w
, but slowed down by the
aerodynamic drag, F
drag
, the rolling resistance, F
rolling
, and the horizontal component of weight. Thus
summing the forces in the x-direction yields:

m x = F
w
C( x + w)
2
mg mgSin 1
Where m is the total mass of the motorcycle and rider, w is the wind speed, is the rolling resistance
coefficient, and C is the aerodynamic drag coefficient, which can be written as:

C =
1
2
AC
d

2
where is the density of air, A is the combined cross-sectional area of the motorcycle and driver and C
d
is
the drag coefficient of the motorcycle and driver. For this study, a linear form of Equation 1 will be used:

m x = F
w
C( x + 2 x w + w
2
) ( + Sin)mg 3
The force on the wheel is generated by a DC permanent magnet motor, which is connected to the
rear wheel of the motorcycle via two sprockets and a chain (Figure 2-2). Mechanical advantage is
achieved by using a sprocket ratio (z), which is defined as:
z = r
sw
/ r
s
4
The sprocket ratio amplifies the torque by a factor of z:

w
= z 5
where is the motor torque, and
w
is the torque on the wheel through the rear sprocket. Summing the
torques from the center point of the rear wheel yields:

J

= z F
w
r
w
6
Where J is the equivalent moment of inertia of both wheels and r
w
is the outer radius of the wheel. The
velocity of the motorcycle is related to the angular velocity of the wheel by the equation:

x =

r
w
7
Thus:


= x / r
w
8
Combining Equations 3, 6 and 8 yields:

J x
r
w
+ m x + C( x + 2 x w + w
2
) + ( + Sin)mg
( )
r
w
= z
9
Which has the Laplace transform of:

mr
w
+
J
r
w






s + Cr
w
(1+ 2w)







X + Cw
2
r
w
+ ( + Sin)mgr
w
= Tz 10
Where L(a) is the Laplace Transform of the variable a:


X = L( x )


T = L()

11


Figure 2-1: Free Body Diagram of the motorcycle. Figure 2-2: Free Body Diagram of the rear
wheel.
The remaining unknown is the torque from the motor, which is set by the user via the throttle
input. Thus, it is desired to relate the input voltage of the motor, V
in
, to the output torque of the motor, .
The motorcycles DC permanent magnet motor can be modeled using resistance, inductance, and back
emf elements as shown in Figure 2-3 [1]. Summing the voltage drops across each element gives the
following relationship:

V
in
= iR +V
emf
+ L
di
dt
12
Where V
in
is the input voltage, i is the current, V
emf
is the back emf voltage, and L is the motor inductance.
The motor will provide a back emf voltage proportional to its angular velocity, which by using Equation 7
can be written as:

V
emf
= K
emf


m
=
K
emf
z
r
w
x
13
The motor torque, , is related to the input current by the torque constant K
t
:

= K
t
i 14
If it is assumed that the motor acts as a perfect force transducer, the torque and back emf constants are
equal:

K
t
= K
emf

15
Now rewriting Equation 12 using Equations 13, 14, and 15:

V
in
=
R
K
t
+
K
t
z
r
w
x +
L
K
t

16
By taking the Laplace transform of Equation 16, the torque can be determined:

T =
K
t
Ls + R
V
in

K
t
z
r
w

X





17
Combining Equations 10 and 17 yields:


X =
V
in
Ls + R
K
t
z
J
r
w
+ mr
w
(
\
|
\
!
|
s + Cr
w
(1+ 2w)
(
\
|
\
!
| +
K
t
z
r
w
|
|
|
|
|
|
|
|

( + sin)mgr
w
+ Cw
2
r
w
J
r
w
+ mr
w
(
\
|
\
!
|
s + C(1+ 2w)r
w
+
K
t
2
z
2
Ls + R ( )r
w
|
|
|
|
|
|

18
Thus the velocity can be written as the sum of two components:


X = G
1
V
in
G
2

19
Where:

G
1
=
1
Ls + R
K
t
z
J
r
w
+ mr
w
(
\
|
\
!
|
s + Cr
w
(1+ 2w)
(
\
|
\
!
| +
K
t
z
r
w
|
|
|
|
|
|
|
|

G
2
=
( + sin)mgr
w
+ Cw
2
r
w
J
r
w
+ mr
w
(
\
|
\
!
|
s + C(1+ 2w)r
w
+
K
t
2
z
2
Ls + R ( )r
w
|
|
|
|
|
|

20
2.2. DeterminingtheSystemConstants
Table B-1 provides a summary of the constants in Equation 20. The aerodynamic coefficients
(Equation 2) were determined by comparing theoretical and experimental estimates of the power required
to maintain a constant speed of 20 m/s on a flat road with a 2 m/s wind. By assuming a more realistic non-
linear aerodynamic drag, the force balance under these conditions is (Equation 1):

F
w
=
1
2
AC
d
(20 + 2)
2
+ mg 21
And the mechanical power required is:

P
w
= F
w
x =
1
2
AC
d
(20 + 2)
2
+ mg





20 22
A power meter was installed on the motorcycle (Figure 2-4), which measured the actual total electrical
power, P
e
, being consumed under these conditions (20 m/s cruising speed with a light wind). Since the
manufacturer states that the motor has an efficiency of 0.88, the mechanical power can be estimated
using:

P
w
= (P
e
P
p
) 0.88
23
Where P
p
is the power required to run the motorcycle lights (approximately 200 Watts). Initial values for
C
d
, A and were obtained from a published reference [2]. Using these published estimates, Equations 22
and 23 agreed with each other by 10%. The values of C
d
and A were adjusted until the results from
Equations 22 and 23 were equal.
Open loop speed versus time plot (Figure 3-1) was plotted for both the simulation and experiment,
and the estimated constants from Table 1 were adjusted within the uncertainty, so the two plots closely
matched. The throttle input was given a generic unit that ranged from 0 (off) to 1000 (full throttle). This
was done to simplify the conversion between motor voltage and speed. Thus a conversion is required to
convert the 0->1000 value to a motor voltage. Since the motor has a maximum voltage of 72 Volts, the
conversion factor is 72/1000. This is the gain in the step to voltage block. The throttle was set to
approximately 630, which corresponded to a steady state speed of roughly 13 m/s. Thus the conversion
between speed (m/s) and 0->1000 is 630/13. This is the gain used in the feedback loop of the closed loop
system to convert velocity to reference velocity.



Figure 2-3: DC motor model. Figure 2-4: The Cycle Analyst power meter.
3. ControllerDesign
The SISO tool in Matlab was initially used to obtain estimates for the gains of the controller required
to meet a rise time of ~4 seconds, and zero steady state error requirements. The plant and controller model
were then simulated using Simulink and the gains were tuned appropriately to obtain precise
specifications. The final gain values were K
p
=3, K
i
=1/2, and K
d
=1/5.
The open loop system is composed of transfer function blocks for the plant and the three
disturbances: rolling resistance, wind, and hills. The plant transfer function is G
1
and the three
disturbances are the components of G
2
(Equation 19). The closed loop system uses a PID controller with a
saturation block to ensure the controller output voltage does not exceed the maximum motor voltage
output of 72 volts (corresponding to a number of 1000). In the closed loop system the output velocity is
converted to a velocity number between 0 (0m/s) and 1000 (20m/s) and the error between this number
and the desired velocity number is fed back into the PID controller. The output of the system is a velocity
in m/s.
A root locus was plotted for the loop transmission of the closed loop system including disturbances,
controller, and plant to determine system stability. Gains were assumed to be at a constant ratio of K
p
=6K
i

and K
p
=15K
d
, which were the same ratios used in the experiments and simulations. The gain K
p
was
varied in this analysis. The root locus plot above is zoomed-in on the dominant poles of the system and
shows that the system is stable for all gains K
p
except for K
p
=0, where the system is marginally stable.
Our system uses K
p
=3 and is thus stable.


Figure 3-1: Open Loop comparison between the
simulation and experiment.


Figure 3-2: Pole-Zero plot of the plant transfer
function.




Table 3-1: Open loop Simulink model.



Table 3-2: Open loop Simulink model.
SimulationResults
The open loop and closed loop systems were simulated using a step input of 630, which
corresponds to 13 m/s. Wind speed was assumed to be zero and the terrain was assumed to be flat. The
90% rise time is 4 seconds as specified in the system requirements and the steady state error is zero. The
motor command is at saturation for the first few seconds, and then decreases as the error decreases. The
command then reaches a nearly steady value, as the error becomes zero.
In the presence of a hill and wind, the open loop response should have a non-zero steady state
error but the closed-loop response to have zero steady state error. This is shown in the simulation with
wind of 1 m/s and hill of 10 degrees (Figure 3-4).
4. ExperimentalSetupandResults
4.1. DescriptionoftheElectricVehicle
The tests were performed on an electric motorcycle built by one of the team members. The
specifications of the motorcycle are listed in Table B-2. A wiring schematic of the power electronics is
shown in Figure B-2. Without closed loop control, the motorcycle is controlled using a 0-5 Volt twist
throttle, which is operated by the driver. The throttle command is sent to a motor controller, which
regulates the power between the batteries and motor.
4.2. ExperimentalPlanandHardware
The driving experiments included both open and closed loop control of the motorcycle. The control
block diagrams for both cases are shown in Figure 4-3 and Figure 4-4.

The algorithm for open loop is as follows:

Figure 3-3: Open and closed loop simulated without
additional disturbances.

Figure 3-4: Open and closed loop simulated for a hill
disturbance.
1. The driver sets the reference (or desired) speed via the twist throttle.
2. This throttle signal is sent directly to the motor controller.
3. The motorcycle accelerates to reach the desired speed.
4. In real time the microcontroller senses the throttle signal and measures the vehicle speed.
This information is time stamped and logged in memory for post-analysis.

The algorithm for closed loop is as follows:
1. The driver sets reference (or desired) speed via the twist throttle.
2. The microcontroller measures the reference speed via the throttle signal.
3. The microcontroller measures the vehicle speed.
4. The microcontroller performs PID algorithm.
5. The microcontroller sends appropriate command to motor controller.
6. In real time the microcontroller senses the reference and command signals and measures the
vehicle speed. This information is time stamped and logged in memory for post-analysis.

Below is a description of how each of the three signals is read or generated, and how the PID algorithm
was formulated.
ReferenceSpeed
The throttle generates an analog signal that varies from 1 Volt (off) to 4 Volts (full on). There is a
linear relationship between the throttle position and the desired speed (e.g. half throttle implies the driver
wants to travel at half of the maximum speed). The Arduino microcontrollers analog to digital converter
(A/D) reads in this signal and assigns values ranging from 0 (0 Volts) to 1018 (5 Volts).
MeasuringSpeed
The speed is measured using a magnetic reed switch and two small magnets (Figure 4-1). The signal
from the switch goes from high (5 Volts) to low (0 Volts) when one of the magnets passes over the
switch. Thus the switch generates a high-low pulse for each half revolution of the front wheel. This pulse
signal is connected to a digital input of the Arduino microcontroller ( Figure 4-6) and the time between
each pulse, t, is determined by measuring the time between the front edge of two consecutive pulses.
Since this time corresponds to the time it took for the wheel to rotate through a half revolution, the speed
can be determined using the following relationship:

x _ =
r
w
36 10
8
t s
24
Where r
w
is the radius of the wheel in meters, t is the time between pulses in milliseconds, and s is the
maximum speed of the motorcycle in meters/second (e.g. 20 m/s).
PIDAlgorithm
For the closed loop case, the speed is measured, and the error is determined as the difference
between the Reference Speed and the Actual Speed:

e _ =V
Th _
x _
25
Where V
Th_
and

x _ are the Reference Speed and Actual Speed, and they vary from zero (0 m/s speed) to
1000 (maximum speed, which is 20 m/s). In general the underscore designates a quantity that varies from
0 to 1000. This universal quantity was required since each of the signals has a different unit. The actual
Command to the motorcycle is determined by applying a PID algorithm to the error [1]:

V
Cmd _
= K
P
e _+ K
I
e _ dt + K
D
de _
dt

26
In practice a discrete approximation must be used:

V
Cmd _
k
= K
P
e
_
k
+ K
I
(e
_
n
t
n
)
n=1
k

+ K
D
e
_
k
e
_
k1
t
k
27
Where t is the change in time between the steps:

t
k
= t
k
t
k1

28
The superscripts are used to designate particular time steps, and should not be confused as exponent
powers.



Figure 4-1: The speed is measured using a reed
magnetic switch and two magnets attached to the
front brake disk.
Figure 4-2: A pulse is generated each time the
magnet passes over the Reed switch. The speed is
measured by measuring the time between pulses.

CommandSignal
The Command signal controls the motor power output via the motor controller. The PID controller
decides the value of this signal. The signal is generated by the microcontroller as a Pulse Width
Modulated (PWM) output, though an RC filter is required to convert the PWM signal to an analog signal.
The resulting analog signal, V
Cmd
,

varies from 0 Volts (zero power) 4 Volts (maximum power) and is sent
to the motor controller.





ExperimentalHardware
The entire loop runs at about 5 Hz. For each case, RC filters were required because of the significant
electromagnetic noise generated by the motor (Figure 4-5). The experimental hardware is shown in
Figure 4-6. A microcontroller was required to measure the input signals, perform calculations, and
command the motor controller. A data logger was used to capture the experimental data in real time. The
motorcycle was rewired to allow the microcontroller to read the throttle measurements and also send
commands to the motor controller. A toggle switch and a quick disconnect was also installed to allow for
rapid reconfiguration between the open and closed loop operations. All of the added hardware was
mounted on a wooden platform and attached to the motorcycle tank with a large magnet. Instead of using
the throttle, a constant reference voltage was achieved by using a small external battery source and a
voltage divider. This reference voltage was connected to an activation switch, so that repeatable step
inputs could be obtained during tests.

Figure 4-3: Open-loop control block diagram.

Figure 4-4: Closed-loop control block diagram.

It should be noted that safety was strongly considered when preparing and performing the driving
tests. Many hours of tests were performed in the lab, and with the motorcycle chain removed. A fake
speed was simulated for these lab tests by spinning a wheel with a magnet in front of the magnetic (reed)
switch. Multiple all-off safety switches were installed on the motorcycle. The computer code was
analyzed thoroughly and safety limits and checks were implemented when possible.

Figure 4-5: Schematic of the experimental hardware.


Figure 4-6: Actual experimental hardware added to
the electric motorcycle.
4.3. InitialExperimentalResults
Figure 4-7 compares Open and Closed Loop for the
driving experiments. It can be seen that the rise time was
reduced from about 10 seconds to roughly 4 seconds,
and there was zero steady state error. The next section
will discuss more of the experimental results in detail,
and compare them with the simulations.
5. ComparisonofSimulationand
ExperimentalResults
It can be seen from Figure 5-1 that the plant model
matches the experimental results within 5% through the
entire test. The closed loop simulation (Figure 5-2),
however, diverges by as much as 7%. It is likely that the
closed loop error is caused by the approximate integration method used (Equation 27). Figure 5-3 shows
how the Riemann sum method likely over estimated the integration in the experiment, and thus the
microcontroller sent an incorrect higher command. Figure 5-4 shows a comparison of closed loop when a
larger integration gain is used, which in effect simulates the overestimate from the Riemann sum. Also
part of the errors could have also been caused by the RC-filters, which were not modeled in the
simulation.
Figure 5-5 shows the voltage (command) signal being applied to the motor by the PID algorithm. As
expected, the controller is initially saturated at a maximum command of 72 Volts. The command then
tapers off to the steady state value of approximately 48 Volts. Figure 5-6 supports the previous prediction
that the error between the simulation and experimentation is caused by the Riemann sum integration.
The final test performed was a step input with a hill/disturbance. Beacon Hill was chosen due to its
steepness and proximity to campus. As before, the step input of 3 Volts (corresponding to 13 m/s) was
applied. As can be seen from Figure 5-7, the model matches the experiment very well at the beginning
and at the end, but there is a significant amount of error (~20%) in the middle. The increased Ohmic
resistance in the motor most likely causes this error. The Ohmic resistance would have likely been much
higher than previously measured in the laboratory because of the difference in motor temperature. The
motor was very hot because it was necessary to drive ~5 KM to the hill, and also drive up and around the
hills a few times before finding an appropriate testing site. Figure 5-8 confirms this theory. Future tests
should include a cool-down period for the motor before executing the tests.

Figure 4-7: Open versus Close Loop
experimental results.


Figure 5-1: Open loop simulation and experimental
results.
Figure 5-2: Closed loop simulation and
experimental results.


Figure 5-3: The Riemann sum integration (blue
dashed lines) overestimates the integral for a
decreasing function.
Figure 5-4: Closed loop simulation and
experimental results with a larger K
I
= 0.7 used for
the simulation. A K
I
= 0.5 was used in the
experiments.

Figure 5-5: Command signal for closed loop
simulation and experimental results.
Figure 5-6: Command signal for closed loop
simulation and experimental results with a larger
K
I
= 0.7 used for the simulation. A K
I
= 0.5 was
used in the experiments.





Figure 5-7: Closed loop speed control going up
Beacon Hill.
Figure 5-8: Closed loop speed control going up
Beacon Hill using a higher R = 0.16 Ohms for the
simulation.
6. Conclusions
A low cost microcontroller, data logger, and RC-filters were used to provide closed loop speed
control of an electric motorcycle. A theoretical plant model was derived, and Matlab/Simulink was used
to determine the appropriate controller gains. Both the simulations and experiments showed that a PID
controller provided the required rise time of 4 seconds and zero steady state error for a step input. There
was ~5% agreement between the model and experiments when factors such as integration error, and
increased thermal resistance in the motor were considered. Thus, it is likely that the motorcycle model
could accurately be used to predict other performance metrics such as power consumption and
acceleration. Our results show that a linear model is adequate at the speeds tested, though it is unlikely to
be appropriate at higher speeds (>13 m/s) due to increased (non-linear) aerodynamic drag.
7. RolesofGroupMembers

Lennon Rodgers built the motorcycle, designed and executed the experimental tests, helped with
the modeling and simulations, and wrote the corresponding sections in the report.
Eric Gilbertson lead the modeling and simulation effort, assisted in the experimental tests, and
wrote the corresponding sections in the report.
Kavya Kamal Manyapu helped in the initial planning of the experimentation and modeling, and
wrote the Introduction and Appendix F.

AppendixA: References
[1] Gene F. Franklin, 2006, Feedback Control of Dynamic Systems, 5th Edition, Prentice Hall
[2] Vittore Cossalter, Motorcycle Dynamics, 2nd Edition


AppendixB: ElectricMotorcycleDetails


Figure B-1: The Electric Vehicle (EV) for this project.


Table B-1: A summary of the constants used in the simulation.

Table B-2: Electric Motorcycle Specifications.
Range: 25-30 miles
Top Speed: 45 MPH
Transmission: Direct drive
Braking: Regenerative and friction
Charging Time: ~6 hours
Energy Requirement: 70 to 75 Watt-hrs/mile
Batteries: 6 x 12 Volt Lead Acid (Sealed, AGM)
Battery Life: 10,000 miles
Voltage: 72 Volts
Motor Power: 9 kWatts Continuous
Electricity Cost: 1.5 cents/mile
Construction Cost: $3000 (total)

Constant Description Method Value
L Inductance of the motor
Measured with inductance
meter
50*10
-6
Hen.
R Resistance of motor Measured with Ohm meter 0.12 Ohm
K
t
Torque constant
Determined from
manufacturers data
0.187 N-m/Amp and
Volt/rad
m
Total mass of motorcycle and
driver
Calculated/Estimated 310 kg
J
Combined Moment of Inertia
for both front and rear wheels
Calculated/Estimated 1.4 kg-m
2

z Sprocket Ratio Fixed 6
r
w
Radius of the wheel Measured/Estimated 0.32 m
C
d
Drag Coefficient Estimated 0.6
A Frontal Area of motorcycle Estimated 0.41 m
2


Figure B-2: Wiring schematic of the power electronics on the electric motorcycle for the Open Loop
configuration.

Table B-3: Hardware added for the PID experiments.
Name Description
Arduino Duemilanove Microcontroller Low cost ($30) commercially available
microcontroller.
Logomatic v2 Serial SD Datalogger Writes serial/UART signals to text files on a
micro-SD card ($60).


AppendixC: MicrocontrollerExperimentalCode

Below is the code for the Arduino microcontroller.

Open Loop:
/*
cruise control for eMoto, the electric motorcycle
*/

int throttle_pin = 2; // select the input pin for the analog input from the throttle
int speed_pin = 7; // pin used to measure the speed signal
long throttle;

//speed specific variables
int speed;
long time1;
long time2;
long time_enter;
long time_current;
int delta_time;
int current_value;
int previous_value;
int flag;
int check;

long speed_time;
long previous_speed_=0;
long temp_speed=0;
long reference_speed_;
long actual_speed_;
long time_stamp;
long velocity_change_squared_;

void setup() {
pinMode(speed_pin, INPUT); // declare the command_pin as an OUTPUT
Serial.begin(9600); // open the serial port at 9600 bps:
}

void loop() {


while (1)
{

//determine desired / reference speed and then convert units to standard 0->1000
throttle = analogRead(throttle_pin); // read the value from the throttle. 0V = 0, 5V = 1018 (187 for zero
throttle to 860 for full throttle from throttle)
reference_speed_ = (throttle-187)*1000/666; //takes the throttle (user input) and converts it to units of 0-
>1000


//determine speed and then convert units from time to standard 0->1000
speed_time = determine_speed(); //returns time between pulses in msec. //it will return 3000ms if the
pause is greater than 1 second.

if (speed_time==3000) //this zeros out the velocity if the pause was greater than 1 second between pulses.
{
actual_speed_ = 0;
}
else
{
actual_speed_ = 54670/speed_time; //the speed put it units of 0->1000

//this checks to make sure the speed didn't suddenly change. This is physically impossible, and is caused
by a faulty speed sensor reading
//this is saying that the difference between the error^2 can never be greater than 90000 (which means that
the abs. value of the diff. in error can never be greater than 300).
velocity_change_squared_ = (actual_speed_ - previous_speed_)*(actual_speed_ - previous_speed_);

if (velocity_change_squared_>90000)
{
actual_speed_ = previous_speed_; //if the new speed measurement "actual_speed" is way off, then just
use the previous measurement
}

previous_speed_ = actual_speed_; //set it for next time around
}


//determine current time
time_stamp = millis();

Serial.print(time_stamp);
Serial.print(", ");
Serial.print(throttle);
Serial.print(", ");
Serial.print(reference_speed_);
Serial.print(", ");
Serial.print(speed_time);
Serial.print(", ");
Serial.println(actual_speed_);



} // outer most while loop
}

//**********************************************
//This function determines the speed of the motorcycle
//**********************************************

int determine_speed() {

int first_run = 1; //a switch used to determine the first time through

time_enter = millis(); //determine the time you enter this loop
flag = 0;

while (1) //loops until two pulses are found. Then continue_loop is set to 0, and kicks out
{ //while loop

if (first_run == 1) //for the first time through we need to measure a value only - since we're doing a
previous / derivative kind of measure
{
current_value = digitalRead(speed_pin);
first_run = 0; //this is used as a switch - to determine the first run through the program.
}

else //this chunk is done all other times besides the first run through
{

previous_value = current_value;
current_value = digitalRead(speed_pin);
check = (current_value+previous_value)*previous_value; //check = 1 means that it went from a 1 to a 0.
A check = 0 means two zeros in a row, and check = 2 means two ones in a row
//Serial.println(check, DEC);

if (check==1 && flag ==0)
{
time1 = millis(); //measure current time
flag = 1;
check = 0; //makese sure it doesn't run into the next if statemnt
}

if (check==1 && flag ==1)
{
time2 = millis(); //measure current time
delta_time = time2-time1;
//Serial.println(delta_time, DEC);
return delta_time;
} //end of if (check==1 && flag ==1)

} //else used for first time through

time_current = millis();

if((time_current-time_enter)>1000) //if it's taking longer than 1 second to determine speed, the speed is
essentially zero, so return a large time value
{
delta_time = 3000;
return delta_time;
}


} //end outer while loop



} //end determine_speed function


Closed Loop:
/*
cruise control for eMoto, the electric motorcycle
*/

int throttle_pin = 2; // select the input pin for the analog input from the throttle
int command_pin = 10; // select the pin that will send commands to the controller
int speed_pin = 7; // pin used to measure the speed signal

long throttle;
int throttle_volts;
long command_value;
long signal_out;

//speed specific variables
int speed;
long time1;
long time2;
long time_enter;
long time_current;
int delta_time;
int current_value;
int previous_value;
int flag;
int check;

long speed_time;
long reference_speed_;
long actual_speed_;
long velocity_change_squared_;
long previous_speed_=0;
long command_;
long command;
long error_;
long error_previous_;

//PID Controller parameters
long proportional_term = 0;
long integral_term = 0;
long derivative_term = 0;
long current_time = 0;
long previous_time = 0;

void setup() {
pinMode(command_pin, OUTPUT); // declare the command_pin as an OUTPUT
pinMode(speed_pin, INPUT); // declare the command_pin as an OUTPUT
Serial.begin(9600); // open the serial port at 9600 bps:
}

void loop() {

previous_time = millis(); //this needs to be done to setup the clock.

while (1)
{

//determine desired / reference speed and then convert units to standard 0->1000
throttle = analogRead(throttle_pin); // read the value from the throttle. 0V = 0, 5V = 1018 (187 for zero
throttle to 860 for full throttle from throttle)
reference_speed_ = (throttle-187)*1000/666; //takes the throttle (user input) and converts it to units of 0-
>1000


if (reference_speed_<20) //this is to turn things off if the user lets go of the throttle. The following is
only done if the throttle is in a go position
{
analogWrite(command_pin, 0); //sets output to zero if user takes hands of throttle

//the following resets the PID values when the user lets off throttle. This prevents windup
integral_term = 0; //reset value otherwise there's windup
error_previous_ = 0; //reset value
error_ = 0; //reset value
previous_time = millis(); //this needs to be done to setup the clock.

}

else //only do the rest of the program if the user has a + input (if the throttle is being twisted) otherwise
just continue to loop and skip most of the program
{

//determine speed and then convert units from time to standard 0->1000
speed_time = determine_speed(); //returns time between pulses in msec. //it will return 3000ms if the
pause is greater than 1 second.

if (speed_time==3000) //this zeros out the velocity if the pause was greater than 1 second between pulses.
{
actual_speed_ = 0;
}
else
{
actual_speed_ = 54670/speed_time; //the speed put it units of 0->1000
//this checks to make sure the speed didn't suddenly change. This is physically impossible, and is caused
by a faulty speed sensor reading
//this is saying that the difference between the error^2 can never be greater than 90000 (which means that
the abs. value of the diff. in error can never be greater than 300).
velocity_change_squared_ = (actual_speed_ - previous_speed_)*(actual_speed_ - previous_speed_);
if (velocity_change_squared_>90000)
{
actual_speed_ = previous_speed_; //if the new speed measurement "actual_speed" is way off, then just
use the previous measurement
}

previous_speed_ = actual_speed_; //set it for next time around
}


//********************************
//need to trim off values, since sometimes they shoot under or over from noise in throttle
if (reference_speed_<=10)
{
reference_speed_ = 0;
}

if (reference_speed_>=990)
{
reference_speed_ = 1000;
}
//********************************

//determine the error: difference between reference and desired. Error here as units from 0->1000
error_previous_ = error_; //used in the PID calculations below for the integral term. We need to know
previous error;
error_ = reference_speed_-actual_speed_;

//this is to prevent oscillations due to small errors in the velocity measurement, etc.
//if(((error_-error_previous_)*(error_-error_previous_))<

/*
Serial.print(error_);
Serial.print(", ");
Serial.print( reference_speed_);
Serial.print(", ");
Serial.println(actual_speed_);
*/

//calls the PID routine, using the error as an input. Error here as units from 0->1000
pid_controller();
//Serial.println(integral_term, DEC);

//converts the 0->1000 units to PWM understanding units: between 0 (always off) and 255 (always on)
command = command_*200/1000 + 55;


//send command signal through PWM
analogWrite(command_pin, command); // value: the duty cycle: between 0 (always off) and 255 (always
on). value: the duty cycle: between 0 (always off) and 255 (always on).

/*
Serial.print("Actual Speed: ");
Serial.print(actual_speed_, DEC);
Serial.print(", ");
Serial.print("Ref Speed: ");
Serial.print(reference_speed_, DEC);
Serial.print(", ");
Serial.print("Error: ");
Serial.print(error_, DEC);
Serial.print(", ");
Serial.print("Command: ");
Serial.println(command_, DEC);

*/

} //If statement right before the while //this is to turn things off if the user lets go of the throttle. The
following is only done if the throttle is in a go position

} // outer most while loop
}

//**********************************************
//This function determines the speed of the motorcycle
//**********************************************

int determine_speed() {

int first_run = 1; //a switch used to determine the first time through

time_enter = millis(); //determine the time you enter this loop
flag = 0;

while (1) //loops until two pulses are found. Then continue_loop is set to 0, and kicks out
{ //while loop

if (first_run == 1) //for the first time through we need to measure a value only - since we're doing a
previous / derivative kind of measure
{
current_value = digitalRead(speed_pin);
first_run = 0; //this is used as a switch - to determine the first run through the program.
}

else //this chunk is done all other times besides the first run through
{

previous_value = current_value;
current_value = digitalRead(speed_pin);
check = (current_value+previous_value)*previous_value; //check = 1 means that it went from a 1 to a 0.
A check = 0 means two zeros in a row, and check = 2 means two ones in a row
//Serial.println(check, DEC);

if (check==1 && flag ==0)
{
time1 = millis(); //measure current time
flag = 1;
check = 0; //makese sure it doesn't run into the next if statemnt
}

if (check==1 && flag ==1)
{
time2 = millis(); //measure current time
delta_time = time2-time1;
//Serial.println(delta_time, DEC);
return delta_time;
} //end of if (check==1 && flag ==1)

} //else used for first time through

time_current = millis();

if((time_current-time_enter)>1000) //if it's taking longer than 1 second to determine speed, the speed is
essentially zero, so return a large time value
{
delta_time = 3000;
return delta_time;
}


} //end outer while loop



} //end determine_speed function

//**********************************************
//PID Routine
//**********************************************

long pid_controller() {


//determining the time step;
current_time = millis();
delta_time = (current_time-previous_time);
previous_time = current_time;
//Serial.println(delta_time, DEC);

//determine the different PID terms
proportional_term = error_*3;
integral_term = error_*delta_time/1000*3/10 + integral_term; //divide by 1000 because time is in msec.
//Since it's an integral, it sums w/ previous value of integral_term
derivative_term = (error_-error_previous_)*1000/delta_time*1/5; //multiply by 1000 because time is in
msec.

//add them together for total PID control


command_ = (proportional_term+integral_term+derivative_term); //devide by 1000 to undo integer math
used in this section


if (command_ >= 1000) //limit check and also to make sure that values don't go over 1000 - this will
cause runover.
{
command_ = 1000; //limit check. Values can only be between 0 and 1000 though the sum above could
provide values outside of the bound
}

if (command_<=10) //limit check. Values can only be between 0 and 1000 though the sum above could
provide values outside of the bound. //there is no physical meaning to a negative command. Though
negative numbers cause overflows and causes a false signal.
{
command_ = 0;
}

Serial.print(current_time);
Serial.print(", ");
Serial.print(throttle);
Serial.print(", ");
Serial.print(reference_speed_);
Serial.print(", ");
Serial.print(speed_time);
Serial.print(", ");
Serial.print(actual_speed_);
Serial.print(", ");
Serial.print(error_, DEC);
Serial.print(", ");
Serial.print(command_, DEC);
Serial.print(", ");
Serial.print(proportional_term, DEC);
Serial.print(", ");
Serial.print(integral_term, DEC);
Serial.print(", ");
Serial.println(derivative_term, DEC);

}

AppendixD: MatlabandSimulinkSimulationCode

%2.140 motorcycle project
%All units are SI

clear all
J=1.4; %combined inertia of both wheels (kg m^2)
L=50*10^-6; %motor inductance (H) at 1kHz
R=0.12; %motor resistance (ohms) at 1kHz
Kt=0.187; %torque constant (and back emf constant) (Nm/A and
Vs/rad)
b=0; %motor damping
rw=0.32; %wheel radius (m)
mu=0.02; %rolling resistance coefficient
m=305; %mass of motorcycle plus rider (kg)
CdA=0.25; %Drag coefficient times approximate frontal area (m^2)
rho=1.2; % air density (kg/m^3)
C=1/2*rho*CdA; %aerodynamic drag coefficient
g=9.8; %gravity (m/s^2)
z=6; %gear ratio'
wind=3; %wind velocity (m/s)
theta=0; %hill angle relative to horizontal in degrees up hill is
positive

%Controller Parameters
Kp=3; %proportional gain
Ki=5/10; %integral gain
Kd=1/5; %derivative gain
% Kp=31.9; %proportional gain
% Ki=5; %integral gain
% Kd=2.8; %derivative gain

numc=[Kp*Kd 0 Kp*Ki];
denc=[1 0];

s=tf([1 0],[1]);

G1=1/((L*s+R)/(Kt*z)*((J/rw+m*rw)*s+C*(1+2*wind)*rw)+Kt*z/rw);
[num,den]=tfdata(G1,'v');

G2=rw/((J/rw+m*rw)*s+C*(1+2*wind)*rw+Kt^2*z^2/((L*s+R)*rw));
[numr,denr]=tfdata(G2,'v');
RollResist=mu*m*g;
WindForce=C*wind^2;
HillForce=m*g*sind(theta);

%for the SISO tool - not really needed...
G2_siso =
(mu*m*g+C*wind^2+m*g*sind(theta))*rw/((J/rw+m*rw)*s+C*(1+2*wind)*rw+Kt
^2*z^2/((L*s+R)*rw));
G1_siso = G1*72/20;

load ExpData_Open.txt
load ExpData_Closed.txt
load ExpData_Hill.txt


sim('motorcycle_closed_loop.mdl')

sim('motorcycle_open_loop.mdl')

AppendixE: OtherMethodsofControllerdesignforElectricVehicles:
By Kavya Manyapu
In order to track longitudinal velocity of an electric motorcycle, one other technique to
design a controller is to employ a feedback linearization strategy. Although our project involves
linear dynamic model for the motorcycle, the advantage of using feedback linearization
technique helps to transform a nonlinear model into a linear closed-loop system via appropriate
control feedback. This allows the use of the linear system theorem to analyze this linear closed
loop system. The values of the design constants can be adjusted appropriately to obtain better
system performance
1
.


Figure E-1: Block Diagram of an electric motorcycle. (Shan Lin, 1999)

Yet other methods that can be used in order to have control of the plant subject to uncertainty
and exogenous disturbance is to make use of some of the advanced analysis and design tools
such as Optimal LQR/Kalman filtering, Adaptive control or robust H

/H
2
controller which
provide a significant improvement in dealing model uncertainty and disturbance attenuation in
comparison to classical linear designs.

Another interesting cruise controller design was done in a study by Lee et.al on electric vehicles
where an intelligent control system was proposed that not only could control the speed of the
electric vehicle, but also provide information about the residual power in the battery system by
monitoring its power consumption. The system consists of both motor driver control and energy
management systems. The driver control subsystem was implemented as a closed-loop speed
control system by using a muscle-like control law with compliant properties
3
. The concept of the
proposed control system that was proposed in the study is shown in figure 2., where DCS is the
drive control subsystem.


Figure E-2: An illustration of the proposed intelligent control system by Lee et.al

The design of the DCS was inspired by the compliant capabilities of the biological limb. The
illustration of the DCS control blocks is shown in figure 3 , which is an excerpt from the paper.

Figure E-3: Drive Control subsystem

The muscle control characteristics were analogs of the DC motor control and the control law for
the electric vehicle was derived relating equations of muscle control to DC motor control, where
for example the muscle force used in the figure above was defined as the DC motor control
voltage Vm
3
. Also the testing of this controller on an electric scooter proved the validity of the
design.



1. Jung-Shan Lin; Li-Chen Fu; Model Analysis and Controller Design of Electric
Motorcycles; Proceedings of the American Control Conference, California June 1999
2. Fenge Yuan, Stabilizing Control Design of a Motorcycle,Thesis,RMIT University 2007
3. Lee,D.T, Dhiah.S.J, Lee,C.M, Wee.C.H; Intelligent Control of Electric Scooters, (366)
Intelligent Systems and Control - 2002

Vous aimerez peut-être aussi