Skip to content

Commit aeaab28

Browse files
committed
Add code for the first assignment
1 parent 0d164f4 commit aeaab28

File tree

1 file changed

+389
-0
lines changed

1 file changed

+389
-0
lines changed

Diff for: tabs.c

+389
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,389 @@
1+
//Array index mnemonics for negative big, medium, and small, zero, and positive small, medium and big.
2+
#define NB 0
3+
#define NM 1
4+
#define NS 2
5+
#define ZE 3
6+
#define PS 4
7+
#define PM 5
8+
#define PB 6
9+
10+
/*
11+
* Optimum wheel slip under braking: S_ref = 0.15. Multiplied by 1000.
12+
*/
13+
#define S_ref 150
14+
15+
/*
16+
* The control signal to hydraulic modulator is calculated periodically once
17+
* every 20 ms. Multiplied by 1000.
18+
*/
19+
#define delta_t 20
20+
21+
/*
22+
* The radius of the wheels is 0.25 m. Multiplied by 1000.
23+
*/
24+
#define R 250
25+
26+
/*
27+
* The table u used to compute the control signal. First index is for error
28+
* (variable e in the function compute_control_signal) and second index for
29+
* error prime (variable ep in the function compute_control_signal). Each
30+
* entry has been multiplied by 1000 and rounded to nearest integer.
31+
*/
32+
// NB NM NS ZE PS PM PB
33+
const int u[7][7] = /*NB*/ {{1000, 1000, 1000, 1000, 667, 333, 0},
34+
/*NM*/ {1000, 1000, 1000, 667, 667, 0, -333},
35+
/*NS*/ {1000, 667, 667, 333, 0, -333, -667},
36+
/*ZE*/ {1000, 667, 333, 0, -333, -667, -1000},
37+
/*PS*/ {667, 333, 0, -333, -667, -667, -1000},
38+
/*PM*/ {333, 0, -667, -667, -1000, -1000, -1000},
39+
/*PB*/ {0, -333, -667, -1000, -1000, -1000, -1000}};
40+
41+
/*
42+
* Dummy variable representing the wheel velocity sensor in radians/s.
43+
* Includes the factor 1000.
44+
*/
45+
int wt_sensor;
46+
47+
/*
48+
* Dummy variable representing the vehicle acceleration sensor in m/s².
49+
* Includes the factor 1000.
50+
*/
51+
int at_sensor;
52+
53+
/*
54+
* Dummy variable representing the sensor of whether the brake pedal is pushed
55+
* or not. Nonzero value is true and zero is false.
56+
*/
57+
int bp_sensor;
58+
59+
/*
60+
* Stores the wheel slip value computed from the last computation of the
61+
* control signal. That is, the last computed wheel slip value.
62+
*/
63+
int S_previous;
64+
65+
/*
66+
* Stores the velocity of the vehicle just before braking. Written each time
67+
* the top-level function hydraulic_modulator_driver is invoked and the brake
68+
* pedal is not pushed. Used to compute the current velocity of the vehicle
69+
* during braking.
70+
*/
71+
int velocity_before_braking;
72+
73+
/*
74+
* Stores the sum of the acceleration samples of the vehicle read during
75+
* braking. Written by hydraulic_modulator_driver. If the brake pedal is not
76+
* pushed, then acceleration_sum is set to the current acceleration of the
77+
* vehicle. If the brake pedal is pushed, then acceleration_sum is added with
78+
* the current acceleration of the vehicle. Hence, acceleration_sum = Σa_i.
79+
* acceleration_sum is used to compute the current velocity of the vehicle.
80+
*/
81+
int acceleration_sum;
82+
83+
/*
84+
* Dummy variable representing the hydraulic modulator. This variable holds
85+
* the value currently being sent to the hydraulic modulator.
86+
*/
87+
int signal_to_hydraulic_modulator;
88+
89+
/******************************************************************************
90+
* The Membership functions µₘ*************************************************
91+
******************************************************************************/
92+
93+
/*
94+
*µNB(x) ≔ 1 if x ≤ -1
95+
*µNB(x) ≔ -2x - 1 if -1 < x < -0.5
96+
*µNB(x) ≔ 0 if -0.5 ≤ x
97+
*/
98+
int mNB(int x) {
99+
if (x <= -1000)
100+
return 1000;
101+
else if (-1000 < x && x <-500)
102+
return -2*x - 1000;
103+
else
104+
return 0;
105+
}
106+
107+
/*
108+
*µNM(x) ≔ 0 if x ≤ -1
109+
*µNM(x) ≔ 2x + 2 if -1 < x ≤ -0.5
110+
*µNM(x) ≔ -4x - 1 if -0.5 < x < -0.25
111+
*µNM(x) ≔ 0 if -0.25 ≤ x
112+
*/
113+
int mNM(int x) {
114+
if (x <= -1000)
115+
return 0;
116+
else if (-1000 < x && x <= -500)
117+
return 2*x + 2000;
118+
else if (-500 < x && x < -250)
119+
return -4*x - 1000;
120+
else
121+
return 0;
122+
}
123+
124+
/*
125+
*µNS(x) ≔ 0 if x ≤ -0.5
126+
*µNS(x) ≔ 4x + 2 if -0.5 < x ≤ -0.25
127+
*µNS(x) ≔ -4x if -0.25 < x < 0
128+
*µNS(x) ≔ 0 if 0 ≤ x
129+
*/
130+
int mNS(int x) {
131+
if (x <= -500)
132+
return 0;
133+
else if (-500 < x && x <= -250)
134+
return 4*x + 2000;
135+
else if (-250 < x && x < 0)
136+
return -4*x;
137+
else
138+
return 0;
139+
}
140+
141+
/*
142+
*µZE(x) ≔ 0 if x ≤ -0.25
143+
*µZE(x) ≔ 4x + 1 if -0.25 < x ≤ 0
144+
*µZE(x) ≔ -4x + 1 if 0 < x < 0.25
145+
*µZE(x) ≔ 0 if 0.25 ≤ x
146+
*/
147+
int mZE(int x) {
148+
if (x <= -250)
149+
return 0;
150+
else if (-250 < x && x <= 0)
151+
return 4*x + 1000;
152+
else if (0 < x && x < 250)
153+
return -4*x + 1000;
154+
else
155+
return 0;
156+
}
157+
158+
/*
159+
*µPS(x) ≔ 0 if x ≤ 0
160+
*µPS(x) ≔ 4x if 0 < x ≤ 0.25
161+
*µPS(x) ≔ -4x + 2 if 0.25 < x < 0.5
162+
*µPS(x) ≔ 0 if 0.5 ≤ x
163+
*/
164+
int mPS(int x) {
165+
if (x <= 0)
166+
return 0;
167+
else if (0 < x && x <= 250)
168+
return 4*x;
169+
else if (250 < x && x < 500)
170+
return -4*x + 2000;
171+
else
172+
return 0;
173+
}
174+
175+
/*
176+
*µPM(x) ≔ 0 if x ≤ 0.25
177+
*µPM(x) ≔ 4x - 1 if 0.25 < x ≤ 0.5
178+
*µPM(x) ≔ -2x + 2 if 0.5 < x < 1
179+
*µPM(x) ≔ 0 if 1 ≤ x
180+
*/
181+
int mPM(int x) {
182+
if (x <= 250)
183+
return 0;
184+
else if (250 < x && x <= 500)
185+
return 4*x - 1000;
186+
else if (500 < x && x < 1000)
187+
return -2*x + 2000;
188+
else
189+
return 0;
190+
}
191+
192+
/*
193+
*µPB(x) ≔ 0 if x ≤ 0.5
194+
*µPB(x) ≔ 2x - 1 if 0.5 < x < 1
195+
*µPB(x) ≔ 1 if 1 ≤ x
196+
*/
197+
int mPB(int x) {
198+
if (x <= 500)
199+
return 0;
200+
else if (500 < x && x < 1000)
201+
return 2*x - 1000;
202+
else
203+
return 1000;
204+
}
205+
206+
/*
207+
* Computes the membership degree.
208+
* index ∈ {NB, NM, NS, ZE, PS, PM, PB}.
209+
* x is e or ep.
210+
*/
211+
int md(int index, int x) {
212+
if (index == NB)
213+
return mNB(x);
214+
else if (index == NM)
215+
return mNM(x);
216+
else if (index == NS)
217+
return mNS(x);
218+
else if (index == ZE)
219+
return mZE(x);
220+
else if (index == PS)
221+
return mPS(x);
222+
else if (index == PM)
223+
return mPM(x);
224+
else
225+
return mPB(x);
226+
}
227+
228+
/******************************************************************************
229+
* End of Membership functions ************************************************
230+
******************************************************************************/
231+
232+
233+
234+
/******************************************************************************
235+
* Dummy functions used to perform input/output *******************************
236+
******************************************************************************/
237+
238+
/*
239+
* Returns the current angular wheel velocity.
240+
*/
241+
int read_wheel_angular_velocity(void) {
242+
return wt_sensor;
243+
}
244+
245+
/*
246+
* Returns the current acceleration of the vehicle.
247+
*/
248+
int read_acceleration_of_vehicle(void) {
249+
return at_sensor;
250+
}
251+
252+
/*
253+
* Returns non-zero if the brake pedal is pushed, and zero if the brake pedal
254+
* is not pushed.
255+
*/
256+
int read_brake_pedal(void) {
257+
return bp_sensor;
258+
}
259+
260+
/*
261+
* Writes uc to the hydraulic modulator.
262+
*/
263+
void write_control_signal_to_hydraulic_modulator(int uc) {
264+
signal_to_hydraulic_modulator = uc;
265+
}
266+
267+
/******************************************************************************
268+
* End of dummy functions used to perform input/output ************************
269+
******************************************************************************/
270+
271+
272+
/*
273+
* Output: Velocity of vehicle = Σa*dt + v0 = v0 + dt⋅Σa.
274+
* First term is divided by 1000 to keep the quantities in terms of 1000,
275+
* since both acceleration_sum and delta_t are already multiplied by 1000.
276+
*/
277+
int compute_velocity_of_vehicle(void) {
278+
return acceleration_sum*delta_t/1000 + velocity_before_braking;
279+
}
280+
281+
/*
282+
* v: Vehicle velocity m/s.
283+
* wt: Angular wheel velocity radians/s.
284+
*
285+
* Output: New wheel slip S.
286+
*/
287+
int compute_wheel_slip(int v, int wt) {
288+
return ((v - wt*R/1000)*1000)/v;
289+
}
290+
291+
/*
292+
* Computes the control signal to the hydraulic modulator.
293+
*/
294+
int compute_control_signal(void) {
295+
int wt = read_wheel_angular_velocity();
296+
297+
int v = compute_velocity_of_vehicle();
298+
299+
int S = compute_wheel_slip(v, wt);
300+
301+
int e = S - S_ref; //error.
302+
303+
int ep = ((S - S_previous)*1000)/delta_t; //error prime.
304+
305+
S_previous = S; //Updates old value of wheel slip.
306+
307+
//Computes the control signal for each of the error and error derivative combinations.
308+
//The code below this for loop is equivalent to this for loop, hopefully. Except for scaling.
309+
// for (error_index = 0; error_index < 7; error_index = error_index + 1)
310+
// for (error_prime_index = 0; error_prime_index < 7; error_prime_index = error_prime_index + 1) {
311+
// int m = md(error_index, error)*md(error_prime_index, error_prime);
312+
// numerator += m*u_table[error_index][error_prime_index];
313+
// denominator += m;
314+
// }
315+
316+
int numerator = 0, denominator = 0;
317+
int ep_sum = md(NB, ep) + md(NM, ep) + md(NS, ep) + md(ZE, ep) + md(PS, ep) + md(PM, ep) + md(PB, ep);
318+
319+
//error is NB. Go through all of {NB, NM, NS, ZE, PS, PM, PB} for error prime.
320+
numerator += md(NB, e)*(md(NB, ep)*u[NB][NB] + md(NM, ep)*u[NB][NM] + md(NS, ep)*u[NB][NS] + md(ZE, ep)*u[NB][ZE] + md(PS, ep)*u[NB][PS] + md(PM, ep)*u[NB][PM] + md(PB, ep)*u[NB][PB])/1000;
321+
322+
//error is NM. Go through all of {NB, NM, NS, ZE, PS, PM, PB} for error prime.
323+
numerator += md(NM, e)*(md(NB, ep)*u[NM][NB] + md(NM, ep)*u[NM][NM] + md(NS, ep)*u[NM][NS] + md(ZE, ep)*u[NM][ZE] + md(PS, ep)*u[NM][PS] + md(PM, ep)*u[NM][PM] + md(PB, ep)*u[NM][PB])/1000;
324+
325+
//error is NS. Go through all of {NB, NM, NS, ZE, PS, PM, PB} for error prime.
326+
numerator += md(NS, e)*(md(NB, ep)*u[NS][NB] + md(NM, ep)*u[NS][NM] + md(NS, ep)*u[NS][NS] + md(ZE, ep)*u[NS][ZE] + md(PS, ep)*u[NS][PS] + md(PM, ep)*u[NS][PM] + md(PB, ep)*u[NS][PB])/1000;
327+
328+
//error is ZE. Go through all of {NB, NM, NS, ZE, PS, PM, PB} for error prime.
329+
numerator += md(ZE, e)*(md(NB, ep)*u[ZE][NB] + md(NM, ep)*u[ZE][NM] + md(NS, ep)*u[ZE][NS] + md(ZE, ep)*u[ZE][ZE] + md(PS, ep)*u[ZE][PS] + md(PM, ep)*u[ZE][PM] + md(PB, ep)*u[ZE][PB])/1000;
330+
331+
//error is PS. Go through all of {NB, NM, NS, ZE, PS, PM, PB} for error prime.
332+
numerator += md(PS, e)*(md(NB, ep)*u[PS][NB] + md(NM, ep)*u[PS][NM] + md(NS, ep)*u[PS][NS] + md(ZE, ep)*u[PS][ZE] + md(PS, ep)*u[PS][PS] + md(PM, ep)*u[PS][PM] + md(PB, ep)*u[PS][PB])/1000;
333+
334+
//error is PM. Go through all of {NB, NM, NS, ZE, PS, PM, PB} for error prime.
335+
numerator += md(PM, e)*(md(NB, ep)*u[PM][NB] + md(NM, ep)*u[PM][NM] + md(NS, ep)*u[PM][NS] + md(ZE, ep)*u[PM][ZE] + md(PS, ep)*u[PM][PS] + md(PM, ep)*u[PM][PM] + md(PB, ep)*u[PM][PB])/1000;
336+
337+
//error is PB. Go through all of {NB, NM, NS, ZE, PS, PM, PB} for error prime.
338+
numerator += md(PB, e)*(md(NB, ep)*u[PB][NB] + md(NM, ep)*u[PB][NM] + md(NS, ep)*u[PB][NS] + md(ZE, ep)*u[PB][ZE] + md(PS, ep)*u[PB][PS] + md(PM, ep)*u[PB][PM] + md(PB, ep)*u[PB][PB])/1000;
339+
340+
denominator += md(NB, e)*ep_sum/1000;
341+
denominator += md(NM, e)*ep_sum/1000;
342+
denominator += md(NS, e)*ep_sum/1000;
343+
denominator += md(ZE, e)*ep_sum/1000;
344+
denominator += md(PS, e)*ep_sum/1000;
345+
denominator += md(PM, e)*ep_sum/1000;
346+
denominator += md(PB, e)*ep_sum/1000;
347+
348+
//Returns uc.
349+
return numerator/denominator;
350+
}
351+
352+
/*
353+
* It is assumed that the interrupt service routine calls this main function
354+
* each time a timer interrupt occurs (once every 0.02 seconds).
355+
*/
356+
void hydraulic_modulator_driver(void) {
357+
//The brake pedal is not pushed.
358+
if (read_brake_pedal() == 0) {
359+
//Reads the current angular velocity of the wheel to compute the
360+
//current velocity of vehicle.
361+
int wt = read_wheel_angular_velocity();
362+
velocity_before_braking = wt*R/1000;
363+
//Stores the current acceleration of the vehicle. The first time
364+
//hydraulic_modulator_driver is invoked when the brake pedal is pushed,
365+
//acceleration_sum is equal to the acceleration of the vehicle just
366+
//before braking. This means that the integration of the acceleration
367+
//over time is done over the time interval that starts when braking
368+
//starts.
369+
acceleration_sum = read_acceleration_of_vehicle();
370+
//No wheel slip since the brakes are not applied and therefore the
371+
//wheels are rolling freely.
372+
S_previous = 0;
373+
//Instructs the hydraulic modulator to not cause any brake pressure.
374+
write_control_signal_to_hydraulic_modulator(-1000);
375+
} else {
376+
//The brake pedal is pushed.
377+
//Adds the current acceleration of the vehicle.
378+
acceleration_sum += read_acceleration_of_vehicle();
379+
//Computes the control signal.
380+
int uc = compute_control_signal();
381+
//Sends the control signal to the hydraulic modulator.
382+
write_control_signal_to_hydraulic_modulator(uc);
383+
}
384+
}
385+
386+
//Dummy function. GCC requires a main function.
387+
int main(void) {
388+
return 0;
389+
}

0 commit comments

Comments
 (0)