mirror of
https://github.com/paparazzi/paparazzi.git
synced 2026-06-01 04:46:51 +08:00
cleanup some unused/outdated stuff from in_progress
This commit is contained in:
@@ -1,40 +0,0 @@
|
|||||||
clear
|
|
||||||
close all
|
|
||||||
|
|
||||||
% DATA
|
|
||||||
t=1:200;
|
|
||||||
orig = sin(t./3)+sin(t./100.*2.*pi);
|
|
||||||
echo = [orig(4:end) 0 0 0]./1.2 + 0.5;
|
|
||||||
echo = echo + randn(size(orig))./10;
|
|
||||||
x = echo;
|
|
||||||
d = orig;
|
|
||||||
|
|
||||||
% RLS
|
|
||||||
rls_p = 5;
|
|
||||||
rls_delta = 1;
|
|
||||||
rls_lambda = 0.95;
|
|
||||||
rls_x = ones(rls_p+1, 1).* x(1);
|
|
||||||
rls_w = ones(rls_p+1, 1)./(rls_p+1);
|
|
||||||
rls_P = eye(rls_p+1) .* rls_delta;
|
|
||||||
|
|
||||||
filt = x;
|
|
||||||
|
|
||||||
for i=t
|
|
||||||
rls_x = [ x(i); rls_x(1:end-2); 1];
|
|
||||||
filt(i) = rls_w' * rls_x;
|
|
||||||
rls_alpha = d(i) - filt(i);
|
|
||||||
rls_g = rls_P * rls_x / (rls_lambda + rls_x' * rls_P * rls_x);
|
|
||||||
rls_P = rls_P / rls_lambda - rls_g*rls_x'* rls_P / rls_lambda;
|
|
||||||
rls_w = rls_w + rls_alpha * rls_g;
|
|
||||||
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
close all;
|
|
||||||
figure;
|
|
||||||
plot(orig,'r');
|
|
||||||
hold on;
|
|
||||||
plot(echo,'b');
|
|
||||||
plot(filt,'g');
|
|
||||||
|
|
||||||
@@ -1,99 +0,0 @@
|
|||||||
clear
|
|
||||||
close all
|
|
||||||
|
|
||||||
% DATA
|
|
||||||
tmax = 200;
|
|
||||||
t=1:tmax;
|
|
||||||
command = zeros(1,tmax);
|
|
||||||
command(50:150) = 1;
|
|
||||||
|
|
||||||
% reference model
|
|
||||||
vref = zeros(1,tmax);
|
|
||||||
vrefdot = 0;
|
|
||||||
|
|
||||||
sysx = 0.2;
|
|
||||||
sysvx = 0;
|
|
||||||
plotsys = zeros(1,tmax);
|
|
||||||
|
|
||||||
integrator = 0;
|
|
||||||
plotint =zeros(1,tmax);
|
|
||||||
|
|
||||||
x = zeros(1,1:tmax);
|
|
||||||
d = zeros(1,1:tmax);
|
|
||||||
filt = zeros(1,1:tmax);
|
|
||||||
|
|
||||||
% RLS
|
|
||||||
rls_p = 5;
|
|
||||||
rls_delta = 1;
|
|
||||||
rls_lambda = 0.95;
|
|
||||||
rls_x = ones(rls_p+1, 1).* x(1);
|
|
||||||
rls_w = ones(rls_p+1, 1)./(rls_p+1);
|
|
||||||
rls_P = eye(rls_p+1) .* rls_delta;
|
|
||||||
|
|
||||||
for i=2:tmax
|
|
||||||
acc = (command(i) - vref(i-1)) / 8 - vrefdot * 0.7 ;
|
|
||||||
if (acc > 0.02)
|
|
||||||
acc = 0.02;
|
|
||||||
elseif (acc<-0.02)
|
|
||||||
acc = -0.02;
|
|
||||||
end
|
|
||||||
vrefdot = vrefdot + acc;
|
|
||||||
if vrefdot > 0.5
|
|
||||||
vrefdot = 0.5
|
|
||||||
elseif vrefdot < -0.5
|
|
||||||
vrefdot = 0.5
|
|
||||||
end
|
|
||||||
vref(i) = vref(i-1) + vrefdot;
|
|
||||||
|
|
||||||
% Control with Integrator
|
|
||||||
error = vref(i) - sysx + rand(1,1) / 20.0;
|
|
||||||
integrator = integrator + error / 2;
|
|
||||||
syscomm = error * 4 + integrator;
|
|
||||||
|
|
||||||
sysacc = (syscomm - (sysx-0.2)*0.75) / 5 - sysvx*0.6;
|
|
||||||
if (sysacc > 0.04)
|
|
||||||
sysacc = 0.04;
|
|
||||||
elseif (sysacc<-0.04)
|
|
||||||
sysacc = -0.04;
|
|
||||||
end
|
|
||||||
sysvx = sysvx + sysacc;
|
|
||||||
if sysvx > 0.6
|
|
||||||
sysvx = 0.6
|
|
||||||
elseif sysvx < -0.7
|
|
||||||
sysvx = 0.7
|
|
||||||
end
|
|
||||||
sysx = sysx + sysvx;
|
|
||||||
|
|
||||||
plotsys(i) = sysx;
|
|
||||||
plotint(i) = integrator;
|
|
||||||
end
|
|
||||||
|
|
||||||
close all
|
|
||||||
figure
|
|
||||||
plot(command , 'r');
|
|
||||||
hold on
|
|
||||||
plot(vref,'g');
|
|
||||||
plot(plotsys,'b')
|
|
||||||
plot(plotint,'k');
|
|
||||||
|
|
||||||
%% Rest
|
|
||||||
|
|
||||||
|
|
||||||
for i=t
|
|
||||||
rls_x = [ x(i); rls_x(1:end-1)];
|
|
||||||
filt(i) = rls_w' * rls_x;
|
|
||||||
rls_alpha = d(i) - filt(i);
|
|
||||||
rls_g = rls_P * rls_x / (rls_lambda + rls_x' * rls_P * rls_x);
|
|
||||||
rls_P = rls_P / rls_lambda - rls_g*rls_x'* rls_P / rls_lambda;
|
|
||||||
rls_w = rls_w + rls_alpha * rls_g;
|
|
||||||
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
figure;
|
|
||||||
plot(orig,'r');
|
|
||||||
hold on;
|
|
||||||
plot(echo,'b');
|
|
||||||
plot(filt,'g');
|
|
||||||
|
|
||||||
@@ -1,429 +0,0 @@
|
|||||||
clear
|
|
||||||
clc
|
|
||||||
close all
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
dt = 1/60;
|
|
||||||
simsteps = 25000;
|
|
||||||
|
|
||||||
timespan=0:1/60:100;
|
|
||||||
|
|
||||||
t = 0;
|
|
||||||
airspeed = 14;
|
|
||||||
acceleration = 0;
|
|
||||||
vclimb = 0;
|
|
||||||
altitude = 100;
|
|
||||||
pitch = 0;
|
|
||||||
alpha = 0;
|
|
||||||
pitch_sp = 0.2;
|
|
||||||
throttle = 0.5;
|
|
||||||
power = 0.25;
|
|
||||||
elevator = 0;
|
|
||||||
|
|
||||||
|
|
||||||
% Altitude command
|
|
||||||
altitude_sp = ones(1,simsteps).* 100;
|
|
||||||
% Airspeed command
|
|
||||||
airspeed_sp = ones(1,simsteps).* 12;
|
|
||||||
|
|
||||||
% slow climb + descend
|
|
||||||
altitude_sp(1,2000:4000) = 125;
|
|
||||||
% fast climb + descend
|
|
||||||
airspeed_sp(1,6000:12000) = 16;
|
|
||||||
altitude_sp(1,8000:10000) = 125;
|
|
||||||
% too low airspeed
|
|
||||||
airspeed_sp(1,13000:14000) = 7;
|
|
||||||
% too high airspeed
|
|
||||||
airspeed_sp(1,15000:16000) = 30;
|
|
||||||
% throttle kill batlow
|
|
||||||
battery_good = ones(1,simsteps);
|
|
||||||
battery_good(1,24000:25000) = 0;
|
|
||||||
% Roll perturbation
|
|
||||||
roll_perturbation = zeros(1,simsteps);
|
|
||||||
% roll oscillation: e.g. poor nav
|
|
||||||
roll_perturbation(1,21000:24000) = abs(sin((21000:24000)./170 .* 6.28));
|
|
||||||
% Headwind changes by making turns
|
|
||||||
% -to keep a constant airspeed, a kinematic acceleration is needed
|
|
||||||
% -or with constant kinetic energy, a change in airspeed is seen
|
|
||||||
wind = zeros(1,simsteps);
|
|
||||||
% 60Hz 70m circle 11m/s 410m = ca 2000 samples
|
|
||||||
wind(1, 17000:23000) = sin((17000:23000)./2000 .* 6.28) .* 5;
|
|
||||||
% derivative of sin is cos so we might also just turn the wind 90deg
|
|
||||||
headwind_induced_kinematic_acceleration = wind .* 0.10;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
% Save states for plotting
|
|
||||||
X = zeros(simsteps,15);
|
|
||||||
extra1 = 0;
|
|
||||||
extra2 = 0;
|
|
||||||
|
|
||||||
% Very ultra-sofisticated Aircraft Model
|
|
||||||
Vmax = 26; % Level flight full power
|
|
||||||
Vmin = 8; % Stall
|
|
||||||
Mass = 1.0;
|
|
||||||
|
|
||||||
% Controller States
|
|
||||||
pitch_cumsum = 0;
|
|
||||||
airspeed_cumsum = 0;
|
|
||||||
|
|
||||||
% RLS
|
|
||||||
rls_p = 3;
|
|
||||||
rls_delta = 0;
|
|
||||||
rls_x = zeros(rls_p+1, 1);
|
|
||||||
rls_w = zeros(rls_p+1, 1);
|
|
||||||
rls_P = eye(rls_p+1) .* rls_delta;
|
|
||||||
|
|
||||||
|
|
||||||
for i=1:simsteps
|
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
% Simplified A/C long dynamics with stall and energy
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
% Pitch loop without integrators
|
|
||||||
pitch_neutral = 0.2;
|
|
||||||
elevator = (pitch_neutral + pitch_sp - pitch) * 15;
|
|
||||||
if (elevator > 0.4)
|
|
||||||
elevator = 0.4;
|
|
||||||
elseif (elevator < -0.2)
|
|
||||||
elevator = -0.2;
|
|
||||||
end
|
|
||||||
% Follow elevator but also align with the flow
|
|
||||||
pitch = pitch + elevator * dt - alpha * dt;
|
|
||||||
% Angle of attack from 0 deg at vmax to 17 deg stall at vmin
|
|
||||||
if airspeed > Vmax
|
|
||||||
alpha = 0;
|
|
||||||
LoverD = 6;
|
|
||||||
elseif airspeed < Vmin
|
|
||||||
% from Vmin downto 0.95 Vmin ... increase alpha from 17 to 45 deg
|
|
||||||
lin = (Vmin-airspeed) / (0.05*Vmin);
|
|
||||||
if (lin > 1)
|
|
||||||
lin = 1;
|
|
||||||
end
|
|
||||||
alpha = (17 + (60-17) * lin) / 57; % complete stall
|
|
||||||
LoverD = 8 - 7 * lin;
|
|
||||||
else
|
|
||||||
alpha = (Vmax - airspeed) / (Vmax-Vmin) * 17.0 / 57;
|
|
||||||
LoverD = 8;
|
|
||||||
end
|
|
||||||
% Path angle
|
|
||||||
gamma = pitch - alpha;
|
|
||||||
vclimb = sin(gamma) * airspeed;
|
|
||||||
altitude = altitude + vclimb * dt;
|
|
||||||
% Using the pitch angle...
|
|
||||||
P_climb = vclimb * Mass;
|
|
||||||
% Lift over Drag
|
|
||||||
P_drag = airspeed / (LoverD / (1+roll_perturbation(i))) * Mass;
|
|
||||||
% Motor Energy
|
|
||||||
power_sp = throttle ^ 2;
|
|
||||||
power = power + (power_sp - power) * 0.1;
|
|
||||||
% Full throttle = same energy as vmax glide
|
|
||||||
P_motor = (Vmax / LoverD) * sqrt(power) * Mass;
|
|
||||||
% Total energy
|
|
||||||
P_tot = P_motor - P_drag - P_climb;
|
|
||||||
|
|
||||||
acceleration = P_tot / Mass + headwind_induced_kinematic_acceleration(i);
|
|
||||||
airspeed = airspeed + (acceleration * dt);
|
|
||||||
|
|
||||||
if (airspeed < Vmin/2)
|
|
||||||
airspeed = Vmin/2;
|
|
||||||
end
|
|
||||||
if (altitude < 0)
|
|
||||||
altitude = 0;
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
controller = 4;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
% Run Control 1: Standard no-airspeed
|
|
||||||
|
|
||||||
if controller == 1
|
|
||||||
Throttle_min = 0.0;
|
|
||||||
Throttle_max = 1.;
|
|
||||||
|
|
||||||
Pitch_min = -30/57;
|
|
||||||
Pitch_max = 45/57;
|
|
||||||
|
|
||||||
VClimb_max = 3;
|
|
||||||
|
|
||||||
|
|
||||||
% Traditional with integrators:
|
|
||||||
|
|
||||||
vclimb_sp = (altitude_sp(i) - altitude);
|
|
||||||
if (vclimb_sp > VClimb_max)
|
|
||||||
vclimb_sp = VClimb_max;
|
|
||||||
elseif (vclimb_sp < -VClimb_max)
|
|
||||||
vclimb_sp = -VClimb_max;
|
|
||||||
end
|
|
||||||
% throttle increment only....
|
|
||||||
throttle = 0.65 + vclimb_sp * 0.9;
|
|
||||||
if (throttle > Throttle_max)
|
|
||||||
throttle = Throttle_max;
|
|
||||||
elseif (throttle < Throttle_min)
|
|
||||||
throttle = Throttle_min;
|
|
||||||
end
|
|
||||||
% pitch of vz
|
|
||||||
pitch_sp = 0.025 + vclimb_sp * 0.05;
|
|
||||||
if (pitch_sp > Pitch_max)
|
|
||||||
pitch_sp = Pitch_max;
|
|
||||||
elseif (pitch_sp < Pitch_min)
|
|
||||||
pitch_sp = Pitch_min;
|
|
||||||
end
|
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
% Run Control 2-3: Old Airspeed Loops
|
|
||||||
% 2: with saturated integrator as most people used
|
|
||||||
% 3: with active integrator
|
|
||||||
|
|
||||||
elseif (controller == 2) || (controller == 3)
|
|
||||||
Throttle_min = 0.0;
|
|
||||||
Throttle_max = 1;
|
|
||||||
|
|
||||||
Pitch_min = -6/57;
|
|
||||||
Pitch_max = 15/57;
|
|
||||||
|
|
||||||
VClimb_max = 1.0;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
% Traditional with integrators:
|
|
||||||
|
|
||||||
vclimb_sp = (altitude_sp(i) - altitude);
|
|
||||||
if (vclimb_sp > VClimb_max)
|
|
||||||
vclimb_sp = VClimb_max;
|
|
||||||
elseif (vclimb_sp < -VClimb_max)
|
|
||||||
vclimb_sp = -VClimb_max;
|
|
||||||
end
|
|
||||||
% I-gain
|
|
||||||
pitch_cumsum = pitch_cumsum + (vclimb_sp - vclimb) * 0.0015;
|
|
||||||
if (pitch_cumsum > Pitch_max)
|
|
||||||
pitch_cumsum = Pitch_max;
|
|
||||||
elseif (pitch_cumsum < Pitch_min)
|
|
||||||
pitch_cumsum = Pitch_min;
|
|
||||||
end
|
|
||||||
% P-gain
|
|
||||||
pitch_sp = pitch_cumsum + vclimb_sp * 0.025;
|
|
||||||
if (pitch_sp > Pitch_max)
|
|
||||||
pitch_sp = Pitch_max;
|
|
||||||
elseif (pitch_sp < Pitch_min)
|
|
||||||
pitch_sp = Pitch_min;
|
|
||||||
end
|
|
||||||
|
|
||||||
err_airspeed = airspeed_sp(i) - airspeed;
|
|
||||||
if (controller == 2)
|
|
||||||
airspeed_cumsum = 0.45;
|
|
||||||
else
|
|
||||||
airspeed_cumsum = airspeed_cumsum + err_airspeed * 0.001;
|
|
||||||
end
|
|
||||||
if (airspeed_cumsum > Throttle_max)
|
|
||||||
airspeed_cumsum = Throttle_max;
|
|
||||||
elseif (airspeed_cumsum < Throttle_min)
|
|
||||||
airspeed_cumsum = Throttle_min;
|
|
||||||
end
|
|
||||||
throttle = airspeed_cumsum + err_airspeed * 0.2;
|
|
||||||
if (throttle > Throttle_max)
|
|
||||||
throttle = Throttle_max;
|
|
||||||
elseif (throttle < Throttle_min)
|
|
||||||
throttle = Throttle_min;
|
|
||||||
end
|
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
% Run Control 4: Feed Forward Gains to climb/accelerate Tcr+Tcl
|
|
||||||
|
|
||||||
elseif controller == 4
|
|
||||||
Throttle_min = 0.0;
|
|
||||||
Throttle_max = 1;
|
|
||||||
|
|
||||||
Pitch_min = -12/57;
|
|
||||||
Pitch_max = 25/57;
|
|
||||||
|
|
||||||
if (airspeed_sp(i) <= 12)
|
|
||||||
VClimb_max = 3;
|
|
||||||
Pitch_max = 10.5/57;
|
|
||||||
Pitch_min = -4.5/57;
|
|
||||||
else
|
|
||||||
VClimb_max = 2;
|
|
||||||
Pitch_max = 3.5/57;
|
|
||||||
Pitch_min = -11/57;
|
|
||||||
end
|
|
||||||
|
|
||||||
% Climb feed forward gain per m/s
|
|
||||||
Tcl = 0.25;
|
|
||||||
% Cruise feed forward gain per m/s
|
|
||||||
Tcr = 1/26;
|
|
||||||
|
|
||||||
% Traditional with integrators:
|
|
||||||
|
|
||||||
vclimb_sp = (altitude_sp(i) - altitude);
|
|
||||||
if (vclimb_sp > VClimb_max)
|
|
||||||
vclimb_sp = VClimb_max;
|
|
||||||
elseif (vclimb_sp < -VClimb_max)
|
|
||||||
vclimb_sp = -VClimb_max;
|
|
||||||
end
|
|
||||||
% I-gain
|
|
||||||
pitch_cumsum = pitch_cumsum + (vclimb_sp - vclimb) * 0.0015;
|
|
||||||
if (pitch_cumsum > Pitch_max)
|
|
||||||
pitch_cumsum = Pitch_max;
|
|
||||||
elseif (pitch_cumsum < Pitch_min)
|
|
||||||
pitch_cumsum = Pitch_min;
|
|
||||||
end
|
|
||||||
% P-gain
|
|
||||||
pitch_sp = pitch_cumsum + vclimb_sp * 0.025;
|
|
||||||
if (pitch_sp > Pitch_max)
|
|
||||||
pitch_sp = Pitch_max;
|
|
||||||
elseif (pitch_sp < Pitch_min)
|
|
||||||
pitch_sp = Pitch_min;
|
|
||||||
end
|
|
||||||
|
|
||||||
err_airspeed = airspeed_sp(i) - airspeed;
|
|
||||||
airspeed_cumsum = airspeed_cumsum + err_airspeed * 0.0005;
|
|
||||||
if (airspeed_cumsum > Throttle_max)
|
|
||||||
airspeed_cumsum = Throttle_max;
|
|
||||||
elseif (airspeed_cumsum < Throttle_min)
|
|
||||||
airspeed_cumsum = Throttle_min;
|
|
||||||
end
|
|
||||||
throttle = airspeed_cumsum + err_airspeed * 0.2 + Tcr * airspeed_sp(i) + Tcl * vclimb_sp;
|
|
||||||
if (throttle > Throttle_max)
|
|
||||||
throttle = Throttle_max;
|
|
||||||
elseif (throttle < Throttle_min)
|
|
||||||
throttle = Throttle_min;
|
|
||||||
end
|
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
% Run Control 5: Feed Forward Gains to climb/accelerate Tcr+Tcl
|
|
||||||
|
|
||||||
elseif controller == 5
|
|
||||||
Throttle_min = 0.0;
|
|
||||||
Throttle_max = 1;
|
|
||||||
|
|
||||||
Pitch_min = -6/57;
|
|
||||||
Pitch_max = 15/57;
|
|
||||||
|
|
||||||
VClimb_max = 1.0;
|
|
||||||
|
|
||||||
if (i==1)
|
|
||||||
% Climb feed forward gain per m/s
|
|
||||||
Tcl = 0.25;
|
|
||||||
% Cruise feed forward gain per m/s
|
|
||||||
Tcr = 1/2000;
|
|
||||||
end
|
|
||||||
|
|
||||||
% Traditional with integrators:
|
|
||||||
|
|
||||||
vclimb_sp = (altitude_sp(i) - altitude);
|
|
||||||
if (vclimb_sp > VClimb_max)
|
|
||||||
vclimb_sp = VClimb_max;
|
|
||||||
elseif (vclimb_sp < -VClimb_max)
|
|
||||||
vclimb_sp = -VClimb_max;
|
|
||||||
end
|
|
||||||
% I-gain
|
|
||||||
pitch_cumsum = pitch_cumsum + (vclimb_sp - vclimb) * 0.0015;
|
|
||||||
if (pitch_cumsum > Pitch_max)
|
|
||||||
pitch_cumsum = Pitch_max;
|
|
||||||
elseif (pitch_cumsum < Pitch_min)
|
|
||||||
pitch_cumsum = Pitch_min;
|
|
||||||
end
|
|
||||||
% P-gain
|
|
||||||
pitch_sp = pitch_cumsum + vclimb_sp * 0.025;
|
|
||||||
if (pitch_sp > Pitch_max)
|
|
||||||
pitch_sp = Pitch_max;
|
|
||||||
elseif (pitch_sp < Pitch_min)
|
|
||||||
pitch_sp = Pitch_min;
|
|
||||||
end
|
|
||||||
|
|
||||||
err_airspeed = airspeed_sp(i) - airspeed;
|
|
||||||
if (abs(vclimb_sp) > 0.5)
|
|
||||||
%Tcl = Tcl + err_airspeed/airspeed_sp(i) * 0.05 * 0.01;
|
|
||||||
Tcr = Tcr + err_airspeed/airspeed_sp(i) * 0.05 * 0.001;
|
|
||||||
else
|
|
||||||
%Tcl = Tcl + err_airspeed/airspeed_sp(i) * 0.05 * 0.001;
|
|
||||||
Tcr = Tcr + err_airspeed/airspeed_sp(i) * 0.05 * 0.01;
|
|
||||||
end
|
|
||||||
throttle = err_airspeed * 0.2 + Tcr * airspeed_sp(i) + Tcl * vclimb_sp;
|
|
||||||
if (throttle > Throttle_max)
|
|
||||||
throttle = Throttle_max;
|
|
||||||
elseif (throttle < Throttle_min)
|
|
||||||
throttle = Throttle_min;
|
|
||||||
end
|
|
||||||
|
|
||||||
extra1 = Tcr;
|
|
||||||
end
|
|
||||||
|
|
||||||
% Autopilot actions
|
|
||||||
if battery_good(i) == 0
|
|
||||||
throttle = 0;
|
|
||||||
end
|
|
||||||
|
|
||||||
% Save For plotting
|
|
||||||
X(i,:) = [ airspeed_sp(i) airspeed altitude_sp(i) altitude throttle power pitch_sp (pitch-pitch_neutral) alpha gamma elevator vclimb_sp vclimb extra1 extra2];
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
figure
|
|
||||||
subplot(6,1,1)
|
|
||||||
hold on
|
|
||||||
plot(airspeed_sp,'r');
|
|
||||||
plot(X(:,2),'b');
|
|
||||||
plot(ones(simsteps,1)*Vmin,'k');
|
|
||||||
plot(ones(simsteps,1)*Vmax,'k');
|
|
||||||
title('Airspeed')
|
|
||||||
axis([0 simsteps Vmin-1 Vmax+1]);
|
|
||||||
grid
|
|
||||||
|
|
||||||
subplot(6,1,2)
|
|
||||||
hold on
|
|
||||||
plot(altitude_sp,'r');
|
|
||||||
plot(X(:,4),'b');
|
|
||||||
title('Altitude')
|
|
||||||
axis([0 simsteps (min(altitude_sp) - 10) (max(altitude_sp)+10)]);
|
|
||||||
grid
|
|
||||||
|
|
||||||
subplot(6,1,3)
|
|
||||||
hold on
|
|
||||||
plot(X(:,5),'r');
|
|
||||||
title('Throttle')
|
|
||||||
axis([0 simsteps 0 1]);
|
|
||||||
grid
|
|
||||||
|
|
||||||
|
|
||||||
subplot(6,1,4)
|
|
||||||
hold on
|
|
||||||
plot(X(:,7)*57,'r');
|
|
||||||
plot(X(:,8)*57,'b');
|
|
||||||
title('Pitch (degrees)')
|
|
||||||
axis([0 simsteps (Pitch_min*57-3) (Pitch_max*57 + 3)]);
|
|
||||||
grid
|
|
||||||
|
|
||||||
subplot(6,1,5)
|
|
||||||
hold on
|
|
||||||
plot(X(:,9)*57,'g');
|
|
||||||
plot(ones(simsteps,1)*17,'r');
|
|
||||||
plot(X(:,10)*57,'k');
|
|
||||||
axis([0 simsteps -10 20]);
|
|
||||||
title('Alpha (green) Gamma (black) (degrees)')
|
|
||||||
%legend('1','2')
|
|
||||||
grid
|
|
||||||
|
|
||||||
subplot(6,1,6)
|
|
||||||
hold on
|
|
||||||
plot(X(:,12),'r');
|
|
||||||
plot(X(:,13),'b');
|
|
||||||
title('VClimb')
|
|
||||||
axis([0 simsteps (-VClimb_max -0.5) (VClimb_max + 0.5)]);
|
|
||||||
grid
|
|
||||||
|
|
||||||
set(gcf,'PaperUnits','centimeter')
|
|
||||||
set(gcf,'PaperSize',[21 30.5])
|
|
||||||
set(gcf,'PaperPosition',[1 1 19 28.5])
|
|
||||||
print(gcf,'-depsc2', ['results_' num2str(controller)]);
|
|
||||||
%print(gcf,'-djpeg', ['results_' num2str(controller)]);
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,109 +0,0 @@
|
|||||||
//
|
|
||||||
// State X = [z; a]
|
|
||||||
// X(k+1) = X(k) + [ a * delta_p; 0]
|
|
||||||
//
|
|
||||||
//
|
|
||||||
|
|
||||||
|
|
||||||
clear();
|
|
||||||
getf('baro_utils.sci');
|
|
||||||
|
|
||||||
//filename = "data/07_08_02__14_57_30.data";
|
|
||||||
//filename = "data/07_08_02__15_19_47.data";
|
|
||||||
//filename = "data/07_09_09__16_23_58.data";
|
|
||||||
filename = "data/test.data";
|
|
||||||
|
|
||||||
[time_pressure, pressure, time_altitude, altitude] = baro_read_pprz_log(filename);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Initialisation
|
|
||||||
//
|
|
||||||
time_start = 110.;
|
|
||||||
time_end = 250.;
|
|
||||||
//time_start = 100.;
|
|
||||||
//time_end = 150.;
|
|
||||||
|
|
||||||
[pressure0,end_pressure, altitude0, end_altitude, a0, b0] = filter_init_timed(time_start, time_end, time_pressure, pressure, time_altitude, altitude)
|
|
||||||
|
|
||||||
X0 = [ altitude0; a0];
|
|
||||||
|
|
||||||
P0 = [ 1. 0.
|
|
||||||
0. 2. ];
|
|
||||||
|
|
||||||
X = [X0];
|
|
||||||
P = [P0];
|
|
||||||
time_state = [time_pressure(end_pressure)];
|
|
||||||
//
|
|
||||||
// Iterations
|
|
||||||
//
|
|
||||||
idx_a = end_altitude;
|
|
||||||
idx_s = 2;
|
|
||||||
for idx_p=(end_pressure+1):length(time_pressure)
|
|
||||||
|
|
||||||
// prediction
|
|
||||||
// initial state
|
|
||||||
X0 = X(:, idx_s-1);
|
|
||||||
// initial covariance
|
|
||||||
P0 = baro_get_P(P, idx_s-1);
|
|
||||||
// command
|
|
||||||
delta_p = pressure(idx_p) - pressure(idx_p-1);
|
|
||||||
delta_z = X0(2) * delta_p;
|
|
||||||
X1 = X0 + [delta_z; 0];
|
|
||||||
// jacobian
|
|
||||||
F = [ 1. delta_p
|
|
||||||
0 1. ];
|
|
||||||
// process covariance noise
|
|
||||||
Q = [ 1e-4 0.
|
|
||||||
0. 1e-7 ];
|
|
||||||
P1 = F*P0*F' + Q;
|
|
||||||
|
|
||||||
// update
|
|
||||||
err = altitude(idx_a) - X1(1);
|
|
||||||
H = [1 0];
|
|
||||||
R = 25;
|
|
||||||
E = H * P1 * H' + R;
|
|
||||||
K = P1 * H' * inv(E);
|
|
||||||
P2 = P1 - K * H * P1;
|
|
||||||
X2 = X1 + K * err;
|
|
||||||
|
|
||||||
X = [X X2];
|
|
||||||
P = [P P2];
|
|
||||||
time_state = [time_state time_pressure(idx_p)];
|
|
||||||
idx_p = idx_p + 1;
|
|
||||||
idx_s = idx_s + 1;
|
|
||||||
while ((idx_p < length(time_pressure)) & ...
|
|
||||||
(time_altitude(idx_a) < time_pressure(idx_p)) & ...
|
|
||||||
(idx_a < length(time_altitude))), idx_a = idx_a + 1; end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
dumb_alt = a0 * pressure + b0;
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Display
|
|
||||||
//
|
|
||||||
xbasc();
|
|
||||||
subplot(4,1,1)
|
|
||||||
xtitle('altitude');
|
|
||||||
plot2d([time_altitude]', [altitude]', style=[5]);
|
|
||||||
plot2d([time_state]', [X(1,:)]', style=[3, 5], leg="est_alt@gps");
|
|
||||||
plot2d([time_pressure]', [dumb_alt]', style=[1]);
|
|
||||||
subplot(4,1,2)
|
|
||||||
xtitle('pressure');
|
|
||||||
plot2d([time_pressure]', [pressure]', style=[5], leg="pressure");
|
|
||||||
subplot(4,1,3)
|
|
||||||
xtitle('a');
|
|
||||||
plot2d([time_state]', [X(2,:)]', style=[3], leg="a");
|
|
||||||
subplot(4,1,4)
|
|
||||||
xtitle('covariance');
|
|
||||||
P11 = [];
|
|
||||||
P22 = [];
|
|
||||||
for i=1:length(time_state)
|
|
||||||
Pi = baro_get_P(P, i);
|
|
||||||
P11 = [P11 Pi(1,1)];
|
|
||||||
P22 = [P22 Pi(2,2)];
|
|
||||||
end
|
|
||||||
plot2d([time_state; time_state]', [P11; P22]', style=[5 3], leg="Palt@Pa");
|
|
||||||
@@ -1,202 +0,0 @@
|
|||||||
function [time, gps_alt, pressure, gps_climb, temp] = baro_read_log(filename)
|
|
||||||
|
|
||||||
time=[];
|
|
||||||
gps_alt=[];
|
|
||||||
pressure=[];
|
|
||||||
gps_climb=[];
|
|
||||||
temp=[];
|
|
||||||
|
|
||||||
u=mopen(filename, 'r');
|
|
||||||
idx = 0;
|
|
||||||
while meof(u) == 0,
|
|
||||||
line = mgetl(u, 1);
|
|
||||||
[nb_scan, ti, ga, p, gc, te] = msscanf(1, line, '%f %f %f %f %f');
|
|
||||||
time = [time ti];
|
|
||||||
gps_alt = [gps_alt ga];
|
|
||||||
pressure = [pressure p];
|
|
||||||
gps_climb = [gps_climb gc];
|
|
||||||
temp = [temp te];
|
|
||||||
end
|
|
||||||
mclose(u);
|
|
||||||
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function [time_pressure, pressure, time_gps, altitude, time_accel, ax_accel, az_accel] = baro_read_pprz_log(filename)
|
|
||||||
|
|
||||||
time_pressure= [];
|
|
||||||
pressure = [];
|
|
||||||
time_gps = [];
|
|
||||||
altitude = [];
|
|
||||||
time_accel = [];
|
|
||||||
ax_accel = [];
|
|
||||||
az_accel = [];
|
|
||||||
|
|
||||||
no_line = 0;
|
|
||||||
u=mopen(filename, 'r');
|
|
||||||
while meof(u) == 0 & no_line < 30000,
|
|
||||||
line = mgetl(u, 1);
|
|
||||||
if (line == "") continue end
|
|
||||||
// printf('%s\n', line);
|
|
||||||
[nb_scan, tip, ac, pr, te, direct_alt] = msscanf(1, line, '%f %d BARO_MS5534A %d %d %f');
|
|
||||||
if (nb_scan == 5)
|
|
||||||
time_pressure = [time_pressure tip];
|
|
||||||
pressure = [pressure pr];
|
|
||||||
else
|
|
||||||
[nb_scan, tig, ac, gmod, gue, gun, gcour, galt, gspeed, gclimb, gitow, guzone, gnerr] = ...
|
|
||||||
msscanf(1, line, '%f %d GPS %d %d %d %d %d %d %d %d %d %d');
|
|
||||||
if (nb_scan == 12)
|
|
||||||
time_gps = [time_gps tig];
|
|
||||||
altitude = [altitude galt];
|
|
||||||
else
|
|
||||||
[nb_scan, tiacc, ac, ax, az] = ...
|
|
||||||
msscanf(1, line, '%f %d ADC_GENERIC %d %d');
|
|
||||||
if (nb_scan == 4)
|
|
||||||
time_accel = [time_accel tiacc];
|
|
||||||
ax_accel = [ax_accel ax];
|
|
||||||
az_accel = [az_accel az];
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
no_line = no_line + 1;
|
|
||||||
end
|
|
||||||
mclose(u);
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
function [baro_alt] = compute_altitude_exp(baro_pressure)
|
|
||||||
P0 = 1013.25;
|
|
||||||
T0 = 288.15;
|
|
||||||
Tg =6.5/1000;
|
|
||||||
R = 287.052;
|
|
||||||
g = 9.81;
|
|
||||||
baro_alt=[];
|
|
||||||
len = length(baro_pressure)
|
|
||||||
for i=1:len
|
|
||||||
ba = T0/Tg*(1-(baro_pressure(i)/P0)^(Tg*R/g));
|
|
||||||
baro_alt=[baro_alt ba];
|
|
||||||
end
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function [baro_alt] = compute_altitude_lin(baro_pressure)
|
|
||||||
baro_alt=[];
|
|
||||||
len = length(baro_pressure)
|
|
||||||
for idx=1:len
|
|
||||||
p = 10 * baro_pressure(idx);
|
|
||||||
if (p > 10300)
|
|
||||||
i = 1638.;
|
|
||||||
j = -139.;
|
|
||||||
pl = 10300.;
|
|
||||||
elseif ( p > 9700 )
|
|
||||||
i = 1720.;
|
|
||||||
j = 365.;
|
|
||||||
pl = 9700.;
|
|
||||||
elseif ( p > 9200 )
|
|
||||||
i = 1802.;
|
|
||||||
j = 805.;
|
|
||||||
pl = 9200.;
|
|
||||||
elseif ( p > 8500 )
|
|
||||||
i = 1905.;
|
|
||||||
j = 1456.;
|
|
||||||
pl = 8500.;
|
|
||||||
elseif ( p > 7800 )
|
|
||||||
|
|
||||||
elseif ( p > 7100 )
|
|
||||||
|
|
||||||
end
|
|
||||||
ba = j - (p-pl) * i / 2^11;
|
|
||||||
baro_alt = [baro_alt ba];
|
|
||||||
end
|
|
||||||
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// intersema application note 501 page 8
|
|
||||||
//
|
|
||||||
function [pres, alt, a, b] = filter_init(avg_len, pressure, gps_alt)
|
|
||||||
|
|
||||||
avg_pressure = sum(pressure(1:avg_len), 'c') / avg_len;
|
|
||||||
avg_gps = sum(gps_alt(1:avg_len), 'c') / avg_len;
|
|
||||||
|
|
||||||
if (avg_pressure > 1030.0)
|
|
||||||
a = -16380. / 2^11;
|
|
||||||
elseif (avg_pressure > 970.0)
|
|
||||||
a = -17200. / 2^11;
|
|
||||||
elseif (avg_pressure > 920.0)
|
|
||||||
a = -18020. / 2^11;
|
|
||||||
elseif (avg_pressure > 850.0)
|
|
||||||
a = -19050. / 2^11;
|
|
||||||
elseif (avg_pressure > 780.0)
|
|
||||||
a = -20330. / 2^11;
|
|
||||||
elseif (avg_pressure > 710.0)
|
|
||||||
a = -21880. / 2^11;
|
|
||||||
elseif (avg_pressure > 650.0)
|
|
||||||
a = -23590. / 2^11;
|
|
||||||
end;
|
|
||||||
|
|
||||||
pres = avg_pressure;
|
|
||||||
alt = avg_gps;
|
|
||||||
b = avg_gps - a * avg_pressure;
|
|
||||||
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
function [pressure0,end_pressure, altitude0, end_altitude, a0, b0] = filter_init_timed(time_start, time_end, time_pressure, pressure, time_altitude, altitude)
|
|
||||||
[avg_pressure, start_pressure, end_pressure] = average_period(time_start, time_end, time_pressure, pressure);
|
|
||||||
[avg_altitude, start_altitude, end_altitude] = average_period(time_start, time_end, time_altitude, altitude);
|
|
||||||
|
|
||||||
if (avg_pressure > 1030.0)
|
|
||||||
a0 = -16380. / 2^11;
|
|
||||||
elseif (avg_pressure > 970.0)
|
|
||||||
a0 = -17200. / 2^11;
|
|
||||||
elseif (avg_pressure > 920.0)
|
|
||||||
a0 = -18020. / 2^11;
|
|
||||||
elseif (avg_pressure > 850.0)
|
|
||||||
a0 = -19050. / 2^11;
|
|
||||||
elseif (avg_pressure > 780.0)
|
|
||||||
a0 = -20330. / 2^11;
|
|
||||||
elseif (avg_pressure > 710.0)
|
|
||||||
a0 = -21880. / 2^11;
|
|
||||||
elseif (avg_pressure > 650.0)
|
|
||||||
a0 = -23590. / 2^11;
|
|
||||||
end;
|
|
||||||
|
|
||||||
pressure0 = avg_pressure;
|
|
||||||
altitude0 = avg_altitude;
|
|
||||||
b0 = avg_altitude - a0 * avg_pressure;
|
|
||||||
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function [average, idx_start, idx_end] = average_period(time_start, time_end, time_samples, samples)
|
|
||||||
idx_start = 1;
|
|
||||||
while ((time_samples(idx_start) < time_start) & (idx_start <= length(time_samples))),
|
|
||||||
idx_start = idx_start+1;
|
|
||||||
end
|
|
||||||
idx_end = idx_start;
|
|
||||||
while ((time_samples(idx_end) < time_end) & (idx_end <= length(time_samples))),
|
|
||||||
idx_end = idx_end+1;
|
|
||||||
end
|
|
||||||
average = sum(samples(idx_start:idx_end), 'c') / (idx_end - idx_start);
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function [Pi] = baro_get_P(P, i)
|
|
||||||
|
|
||||||
Pi = P(:, 2*i-1:2*i);
|
|
||||||
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function [Pi] = baro_get_P3(P, i)
|
|
||||||
|
|
||||||
Pi = P(:, 3*i-2:3*i);
|
|
||||||
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
function [X1, P1] = ekf_predict_continuous(X0, X0dot, dt, P0, F, Q)
|
|
||||||
|
|
||||||
X1 = X0 + X0dot * dt;
|
|
||||||
P0dot = F*P0 + P0*F' + Q;
|
|
||||||
P1 = P0 + P0dot * dt;
|
|
||||||
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
function [X1, P1] = ekf_predict_discrete(X0, X0dot, dt, P0, F, Q)
|
|
||||||
|
|
||||||
X1 = X0 + X0dot * dt;
|
|
||||||
expF = expm(dt * F);
|
|
||||||
P0dot = expF*P0*expF' + Q;
|
|
||||||
P1 = P0 + P0dot * dt;
|
|
||||||
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
function [X1, P1] = ekf_update(X0, P0, H, R, err)
|
|
||||||
|
|
||||||
E = H * P0 * H' + R;
|
|
||||||
K = P0 * H' * inv(E);
|
|
||||||
P1 = P0 - K * H * P0;
|
|
||||||
X1 = X0 + K * err;
|
|
||||||
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
clear();
|
|
||||||
getf('baro_utils.sci');
|
|
||||||
|
|
||||||
filename = "data/07_07_26__16_37_09.baro.txt";
|
|
||||||
[time, gps_alt, pressure, gps_climb, temp] = baro_read_log(filename);
|
|
||||||
|
|
||||||
|
|
||||||
[p0, z0, a, b] = filter_init(10, pressure, gps_alt)
|
|
||||||
|
|
||||||
if 0
|
|
||||||
deff('e=G(p,z)','a=p(1),b=p(2), gps=z(1), pressure=z(2), e=gps-(a/pressure+b)')
|
|
||||||
deff('dg=dG(p,z)','a=p(1),b=p(2), gps=z(1), pressure=z(2), dg = [-1/pressure; -b]')
|
|
||||||
p0 = [a, 0]';
|
|
||||||
[p, err] = fit_dat(G, p0, [gps_alt; pressure], [1], dG)
|
|
||||||
|
|
||||||
a = p(1)
|
|
||||||
b = p(2)
|
|
||||||
end
|
|
||||||
|
|
||||||
baro_alt_lin = a * pressure + b;
|
|
||||||
baro_alt_full = compute_altitude_exp(pressure);
|
|
||||||
//baro_alt = compute_altitude_lin(pressure);
|
|
||||||
|
|
||||||
xbasc();
|
|
||||||
if 0
|
|
||||||
subplot(3,1,1)
|
|
||||||
xtitle('Gps');
|
|
||||||
plot2d([time], [gps_alt]);
|
|
||||||
subplot(3,1,2)
|
|
||||||
xtitle('Pressure');
|
|
||||||
plot2d([time], [pressure]);
|
|
||||||
subplot(3,1,3)
|
|
||||||
end
|
|
||||||
xtitle('Both');
|
|
||||||
plot2d([time; time; time]', [gps_alt; baro_alt_full; baro_alt_lin]', style=[5, 3, 2], leg="gps@barofull@barolin");
|
|
||||||
@@ -1,141 +0,0 @@
|
|||||||
//
|
|
||||||
// State X = [z; a]
|
|
||||||
// X(k+1) = X(k) + [ a * delta_p; 0]
|
|
||||||
//
|
|
||||||
//
|
|
||||||
|
|
||||||
|
|
||||||
clear();
|
|
||||||
getf('baro_utils.sci');
|
|
||||||
|
|
||||||
//filename = "data/07_08_02__14_57_30.data";
|
|
||||||
//filename = "data/07_08_02__15_19_47.data";
|
|
||||||
//filename = "data/07_09_09__16_23_58.data";
|
|
||||||
filename = "data/test.data";
|
|
||||||
|
|
||||||
[time_pressure, pressure, time_altitude, altitude, time_accel, accel_x, accel_z] = baro_read_pprz_log(filename);
|
|
||||||
|
|
||||||
acc_neutral = 512;
|
|
||||||
acc_gain = 2. / 400 * 9.81;
|
|
||||||
|
|
||||||
ax_ms2 = (accel_x - acc_neutral) * acc_gain;
|
|
||||||
az_ms2 = (accel_z - acc_neutral) * acc_gain;
|
|
||||||
|
|
||||||
norm_accel = sqrt( ax_ms2^2 + az_ms2^2);
|
|
||||||
meas_pitch = atan(-az_ms2, ax_ms2);
|
|
||||||
z_dot = [0.]
|
|
||||||
|
|
||||||
//
|
|
||||||
// Initialisation
|
|
||||||
//
|
|
||||||
time_start = 110.;
|
|
||||||
time_end = 250.;
|
|
||||||
//time_start = 100.;
|
|
||||||
//time_end = 150.;
|
|
||||||
|
|
||||||
[pressure0,end_pressure, altitude0, end_altitude, a0, b0] = filter_init_timed(time_start, time_end, time_pressure, pressure, time_altitude, altitude)
|
|
||||||
|
|
||||||
zdot_0 = 0.;
|
|
||||||
|
|
||||||
X0 = [ altitude0; zdot_0];
|
|
||||||
|
|
||||||
P0 = [ 1. 0.
|
|
||||||
0. 2. ];
|
|
||||||
|
|
||||||
X = [X0];
|
|
||||||
P = [P0];
|
|
||||||
time_state = [time_pressure(end_pressure)];
|
|
||||||
//
|
|
||||||
// Iterations
|
|
||||||
//
|
|
||||||
idx_a = end_altitude;
|
|
||||||
idx_acc = 1;
|
|
||||||
while idx_acc < length(time_accel) & time_accel(idx_acc) < time_pressure(end_pressure), idx_acc = idx_acc + 1; end
|
|
||||||
idx_s = 2;
|
|
||||||
for idx_p=(end_pressure+1):length(time_pressure)
|
|
||||||
|
|
||||||
// prediction
|
|
||||||
// initial state
|
|
||||||
X0 = X(:, idx_s-1);
|
|
||||||
// initial covariance
|
|
||||||
P0 = baro_get_P(P, idx_s-1);
|
|
||||||
// command
|
|
||||||
delta_p = pressure(idx_p) - pressure(idx_p-1);
|
|
||||||
delta_z = a0 * delta_p;
|
|
||||||
X1 = X0 + [delta_z; 0];
|
|
||||||
// jacobian
|
|
||||||
F = [ 1. delta_p
|
|
||||||
0 1. ];
|
|
||||||
// process covariance noise
|
|
||||||
Q = [ 1e-4 0.
|
|
||||||
0. 1e-7 ];
|
|
||||||
P1 = F*P0*F' + Q;
|
|
||||||
|
|
||||||
// update
|
|
||||||
z_dot_m = (norm_accel(idx_acc) - 9.81) * (time_accel(idx_acc) - time_accel(idx_acc - 1)) + X(2, idx_p-end_pressure);
|
|
||||||
z_dot = [z_dot z_dot_m];
|
|
||||||
err = z_dot_m - X1(2);
|
|
||||||
H = [0 1];
|
|
||||||
R = 25;
|
|
||||||
E = H * P1 * H' + R;
|
|
||||||
K = P1 * H' * inv(E);
|
|
||||||
P2 = P1 - K * H * P1;
|
|
||||||
X2 = X1 + K * err;
|
|
||||||
|
|
||||||
X = [X X2];
|
|
||||||
P = [P P2];
|
|
||||||
time_state = [time_state time_pressure(idx_p)];
|
|
||||||
idx_p = idx_p + 1;
|
|
||||||
idx_s = idx_s + 1;
|
|
||||||
while ((idx_p < length(time_pressure)) & ...
|
|
||||||
(time_altitude(idx_a) < time_pressure(idx_p)) & ...
|
|
||||||
(idx_a < length(time_altitude))), idx_a = idx_a + 1; end
|
|
||||||
|
|
||||||
while ((idx_p < length(time_pressure)) & ...
|
|
||||||
(time_accel(idx_acc) < time_pressure(idx_p)) & ...
|
|
||||||
(idx_acc < length(time_accel))), idx_acc = idx_acc + 1; end
|
|
||||||
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
dumb_alt = a0 * pressure + b0;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Display
|
|
||||||
//
|
|
||||||
xbasc();
|
|
||||||
subplot(6,1,1)
|
|
||||||
xtitle('altitude');
|
|
||||||
plot2d([time_altitude]', [altitude]', style=[5]);
|
|
||||||
plot2d([time_state]', [X(1,:)]', style=[3, 5], leg="est_alt@gps");
|
|
||||||
plot2d([time_pressure]', [dumb_alt]', style=[1]);
|
|
||||||
subplot(6,1,2)
|
|
||||||
xtitle('pressure');
|
|
||||||
plot2d([time_pressure]', [pressure]', style=[5], leg="pressure");
|
|
||||||
subplot(6,1,3)
|
|
||||||
xtitle('z_dot');
|
|
||||||
plot2d([time_state]', [X(2,:)]', style=[3], leg="zdot_est");
|
|
||||||
plot2d([time_state]', [z_dot]', style=[3], leg="zdot_meas");
|
|
||||||
subplot(6,1,4)
|
|
||||||
xtitle('covariance');
|
|
||||||
P11 = [];
|
|
||||||
P22 = [];
|
|
||||||
for i=1:length(time_state)
|
|
||||||
Pi = baro_get_P(P, i);
|
|
||||||
P11 = [P11 Pi(1,1)];
|
|
||||||
P22 = [P22 Pi(2,2)];
|
|
||||||
end
|
|
||||||
plot2d([time_state; time_state]', [P11; P22]', style=[5 3], leg="Pzt@Pzdot");
|
|
||||||
|
|
||||||
|
|
||||||
subplot(6,1,5)
|
|
||||||
plot2d([time_accel; time_accel; time_accel]', [ax_ms2; az_ms2; norm_accel]', style=[5 3 2], leg="Ax@Az@anorm");
|
|
||||||
|
|
||||||
|
|
||||||
subplot(6,1,6)
|
|
||||||
plot2d([time_accel]', [meas_pitch]', style=[5 3 2], leg="Ax@Az@anorm");
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
<conf>
|
|
||||||
<aircraft
|
|
||||||
name="R1"
|
|
||||||
ac_id="26"
|
|
||||||
airframe="airframes/red_one.xml"
|
|
||||||
radio="radios/mc24.xml"
|
|
||||||
telemetry="telemetry/default.xml"
|
|
||||||
flight_plan="flight_plans/ccc_gl.xml"
|
|
||||||
settings="settings/cam.xml settings/tuning.xml settings/switch.xml"
|
|
||||||
gui_color="yellow"
|
|
||||||
/>
|
|
||||||
<aircraft
|
|
||||||
name="TJ1"
|
|
||||||
ac_id="6"
|
|
||||||
airframe="airframes/twinjet1.xml"
|
|
||||||
radio="radios/cockpitSX.xml"
|
|
||||||
telemetry="telemetry/default.xml"
|
|
||||||
flight_plan="flight_plans/basic.xml"
|
|
||||||
settings="settings/light.xml settings/tuning.xml"
|
|
||||||
gui_color="#ba6293"
|
|
||||||
/>
|
|
||||||
</conf>
|
|
||||||
@@ -1,134 +0,0 @@
|
|||||||
<?xml version="1.0"?>
|
|
||||||
|
|
||||||
<control_panel name="paparazzi control panel">
|
|
||||||
|
|
||||||
<section name="variables">
|
|
||||||
<variable name="downlink_serial_port" value="/dev/ttyUSB0"/>
|
|
||||||
<variable name="fbw_serial_port" value="/dev/ttyS1"/>
|
|
||||||
<variable name="ap_serial_port" value="/dev/ttyS0"/>
|
|
||||||
<variable name="ivy_bus" value="127:2010"/>
|
|
||||||
<variable name="map" value="muret_UTM.xml"/>
|
|
||||||
<variable name="flight_plan" value="flight_plans/muret1.xml"/>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section name="programs">
|
|
||||||
<program name="Server" command="sw/ground_segment/tmtc/server">
|
|
||||||
<arg flag="-b" variable="ivy_bus"/>
|
|
||||||
</program>
|
|
||||||
|
|
||||||
<program name="Data Link" command="sw/ground_segment/tmtc/link">
|
|
||||||
<arg flag="-b" variable="ivy_bus"/>
|
|
||||||
</program>
|
|
||||||
|
|
||||||
<program name="GCS" command="sw/ground_segment/cockpit/gcs">
|
|
||||||
<arg flag="-b" variable="ivy_bus"/>
|
|
||||||
</program>
|
|
||||||
|
|
||||||
<program name="Flight Plan Editor" command="sw/ground_segment/cockpit/gcs -edit">
|
|
||||||
</program>
|
|
||||||
|
|
||||||
<program name="Messages" command="sw/ground_segment/tmtc/messages">
|
|
||||||
<arg flag="-b" variable="ivy_bus"/>
|
|
||||||
</program>
|
|
||||||
|
|
||||||
<program name="Settings" command="sw/ground_segment/tmtc/settings">
|
|
||||||
<arg flag="-b" variable="ivy_bus"/>
|
|
||||||
</program>
|
|
||||||
|
|
||||||
<program name="Log Plotter" command ="sw/logalizer/plot"/>
|
|
||||||
|
|
||||||
<program name="Real-time Plotter" command ="sw/logalizer/plotter"/>
|
|
||||||
|
|
||||||
<program name="Log File Player" command="sw/logalizer/play">
|
|
||||||
<arg flag="-b" variable="ivy_bus"/>
|
|
||||||
</program>
|
|
||||||
|
|
||||||
<program name="Simulator" command="sw/simulator/launchsitl">
|
|
||||||
<arg flag="-b" variable="ivy_bus"/>
|
|
||||||
</program>
|
|
||||||
|
|
||||||
<program name="Hardware in the Loop" command="sw/simulator/simhitl">
|
|
||||||
<arg flag="-fbw" variable="fbw_serial_port"/>
|
|
||||||
<arg flag="-ap" variable="ap_serial_port"/>
|
|
||||||
</program>
|
|
||||||
|
|
||||||
<program name="Environment Simulator" command="sw/simulator/gaia">
|
|
||||||
<arg flag="-b" variable="ivy_bus"/>
|
|
||||||
</program>
|
|
||||||
|
|
||||||
<program name="Http Server" command="sw/ground_segment/tmtc/boa"/>
|
|
||||||
|
|
||||||
<program name="TCP controller" command="sw/ground_segment/tmtc/ivy_tcp_controller"/>
|
|
||||||
<program name="TCP aircraft" command="sw/ground_segment/tmtc/ivy_tcp_aircraft"/>
|
|
||||||
<program name="Spook" command="sw/in_progress/videolizer/spook/spook"/>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<section name="sessions">
|
|
||||||
|
|
||||||
<session name="Berlin">
|
|
||||||
<program name="Server"/>
|
|
||||||
<program name="GCS">
|
|
||||||
<arg flag="-mplayer" constant="rtsp://ricou.homelinux.org:7070/webcam"/>
|
|
||||||
<arg flag="-layout" constant="layout_berlin.xml"/>
|
|
||||||
</program>
|
|
||||||
<program name="TCP controller">
|
|
||||||
<arg flag="-h" constant="85.214.48.162"/>
|
|
||||||
</program>
|
|
||||||
</session>
|
|
||||||
|
|
||||||
<session name="Toulouse">
|
|
||||||
<program name="Data Link">
|
|
||||||
<arg flag="-d" constant="/dev/ttyUSB0"/>
|
|
||||||
<arg flag="-s" constant="57600"/>
|
|
||||||
<arg flag="-aerocomm" constant=""/>
|
|
||||||
</program>
|
|
||||||
<program name="Server"/>
|
|
||||||
<program name="GCS"/>
|
|
||||||
<program name="TCP aircraft">
|
|
||||||
<arg flag="-h" constant="85.214.48.162"/>
|
|
||||||
</program>
|
|
||||||
<program name="Spook">
|
|
||||||
<arg flag="-c" constant="/home/pascal/pprz/savannah/paparazzi3/sw/in_progress/videolizer/spook/spook.conf.usbraw"/>
|
|
||||||
</program>
|
|
||||||
</session>
|
|
||||||
|
|
||||||
<session name="Hildesheim">
|
|
||||||
<program name="Data Link">
|
|
||||||
<arg flag="-d" constant="/dev/ttyUSB0"/>
|
|
||||||
</program>
|
|
||||||
<program name="Server"/>
|
|
||||||
<program name="GCS">
|
|
||||||
<arg flag="-layout" constant="layout_berlin.xml"/>
|
|
||||||
<arg flag="-mplayer" constant="rtsp://localhost:7070/webcam"/>
|
|
||||||
</program>
|
|
||||||
<program name="TCP aircraft">
|
|
||||||
<arg flag="-h" constant="85.214.48.162"/>
|
|
||||||
<arg flag="-id" constant="26"/>
|
|
||||||
</program>
|
|
||||||
<program name="Spook">
|
|
||||||
<arg flag="-c" constant="/home/mum2hi/uav/paparazzi3/sw/in_progress/videolizer/spook/spook.conf"/>
|
|
||||||
</program>
|
|
||||||
</session>
|
|
||||||
|
|
||||||
|
|
||||||
<session name="simulation">
|
|
||||||
<program name="Server"/>
|
|
||||||
<program name="GCS"> </program>
|
|
||||||
<program name="Simulator">
|
|
||||||
<arg flag="-a" constant="TJ1"/>
|
|
||||||
<arg flag="-norc" constant=""/>
|
|
||||||
</program>
|
|
||||||
<program name="Simulator">
|
|
||||||
<arg flag="-a" constant="R1"/>
|
|
||||||
<arg flag="-norc" constant=""/>
|
|
||||||
</program>
|
|
||||||
</session>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</section>
|
|
||||||
|
|
||||||
</control_panel>
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
<!DOCTYPE layout SYSTEM "layout.dtd">
|
|
||||||
|
|
||||||
<layout width="1024" height="768">
|
|
||||||
<columns>
|
|
||||||
<rows size="400">
|
|
||||||
<widget size="300" name="strips"/>
|
|
||||||
<widget size="300" name="plugin"/>
|
|
||||||
<widget name="alarms"/>
|
|
||||||
</rows>
|
|
||||||
<rows>
|
|
||||||
<widget name="map2d"/>
|
|
||||||
<widget name="aircraft"/>
|
|
||||||
</rows>
|
|
||||||
</columns>
|
|
||||||
</layout>
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
#
|
|
||||||
# $Id$
|
|
||||||
# Copyright (C) 2004 Pascal Brisset, Antoine Drouin
|
|
||||||
#
|
|
||||||
# This file is part of paparazzi.
|
|
||||||
#
|
|
||||||
# paparazzi is free software; you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License as published by
|
|
||||||
# the Free Software Foundation; either version 2, or (at your option)
|
|
||||||
# any later version.
|
|
||||||
#
|
|
||||||
# paparazzi is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with paparazzi; see the file COPYING. If not, write to
|
|
||||||
# the Free Software Foundation, 59 Temple Place - Suite 330,
|
|
||||||
# Boston, MA 02111-1307, USA.
|
|
||||||
#
|
|
||||||
|
|
||||||
# Quiet compilation
|
|
||||||
Q=@
|
|
||||||
|
|
||||||
all: fdm_step
|
|
||||||
|
|
||||||
fdm_step: fdm_step.c
|
|
||||||
gcc -g -O2 -Wall $(shell pkg-config glib-2.0 --cflags) -o $@ $^ $(shell pkg-config glib-2.0 --libs) -lglibivy
|
|
||||||
|
|
||||||
|
|
||||||
fms_steps_attitude: fms_steps_attitude.c
|
|
||||||
gcc -g -O2 -Wall $(shell pkg-config glib-2.0 --cflags) -o $@ $^ $(shell pkg-config glib-2.0 --libs) -lglibivy
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
clean:
|
|
||||||
$(Q)rm -f *~ core *.o *.bak .depend fdm_step fms_steps_attitude
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
#ifndef BOOZ2_FMS_EXTERN_H
|
|
||||||
#define BOOZ2_FMS_EXTERN_H
|
|
||||||
|
|
||||||
#define FMS_H_MODE_RATE 0
|
|
||||||
#define FMS_H_MODE_ATTITUDE 1
|
|
||||||
#define FMS_H_MODE_SPEED 2
|
|
||||||
#define FMS_H_MODE_POS 3
|
|
||||||
|
|
||||||
#define FMS_ATTITUDE_OF_DEG(_d) ((int32_t)((_d)*0.0000546))
|
|
||||||
|
|
||||||
#define FMS_V_MODE_DIRECT 0
|
|
||||||
#define FMS_V_MODE_CLIMB 1
|
|
||||||
#define FMS_V_MODE_HEIGHT 2
|
|
||||||
|
|
||||||
//#define BOOZ2_SEND_IVY_FMS_COMMAND
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* BOOZ2_FMS_EXTERN_H */
|
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
/*
|
|
||||||
* fdm_step
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <glib.h>
|
|
||||||
#include <Ivy/ivy.h>
|
|
||||||
#include <Ivy/ivyglibloop.h>
|
|
||||||
|
|
||||||
#define TIMEOUT_PERIOD 100
|
|
||||||
|
|
||||||
#define DEFAULT_AC_ID 1
|
|
||||||
|
|
||||||
/* Options */
|
|
||||||
static int aircraft_id = DEFAULT_AC_ID;
|
|
||||||
static int counter;
|
|
||||||
|
|
||||||
void parse_args(int argc, char * argv[])
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 1; i < argc; i++) {
|
|
||||||
if (!strcmp(argv[i],"-a") && i<argc-1) aircraft_id = atoi(argv[++i]);
|
|
||||||
else if (!strcmp(argv[i],"-h")) goto l_help;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
|
|
||||||
l_help:
|
|
||||||
printf("Usage:\n");
|
|
||||||
printf(" %s <option> [<option>...]\n",argv[0]);
|
|
||||||
printf("Options:\n");
|
|
||||||
printf(" -a <int> aircraft id (default: %d)\n",DEFAULT_AC_ID);
|
|
||||||
printf(" -h display this help\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define STEP_VAL 127
|
|
||||||
static gboolean periodic(gpointer data __attribute__ ((unused))) {
|
|
||||||
int roll, pitch;
|
|
||||||
counter++;
|
|
||||||
pitch = 0;
|
|
||||||
roll = STEP_VAL;
|
|
||||||
if ((counter%6) >=3) roll = -roll;
|
|
||||||
|
|
||||||
IvySendMsg("dl COMMANDS_RAW %d %d,%d", aircraft_id, roll, pitch);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int main ( int argc, char** argv) {
|
|
||||||
|
|
||||||
GMainLoop *ml = g_main_loop_new(NULL, FALSE);
|
|
||||||
|
|
||||||
parse_args(argc, argv);
|
|
||||||
|
|
||||||
IvyInit ("IvyFdmStep", "IvyFdmStep READY", NULL, NULL, NULL, NULL);
|
|
||||||
IvyStart("127.255.255.255");
|
|
||||||
|
|
||||||
g_timeout_add(TIMEOUT_PERIOD, periodic, NULL);
|
|
||||||
|
|
||||||
g_main_loop_run(ml);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,103 +0,0 @@
|
|||||||
/*
|
|
||||||
* fms_steps_attitude
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <glib.h>
|
|
||||||
#include <Ivy/ivy.h>
|
|
||||||
#include <Ivy/ivyglibloop.h>
|
|
||||||
|
|
||||||
#include <inttypes.h>
|
|
||||||
#include "booz2_fms_extern.h"
|
|
||||||
|
|
||||||
|
|
||||||
#define TIMEOUT_PERIOD 100
|
|
||||||
#define DEFAULT_AC_ID 150
|
|
||||||
#define STEP_VAL 2
|
|
||||||
#define STEP_PERIOD 3
|
|
||||||
|
|
||||||
static int aircraft_id = DEFAULT_AC_ID;
|
|
||||||
static int counter;
|
|
||||||
|
|
||||||
static gboolean periodic(gpointer data __attribute__ ((unused)));
|
|
||||||
|
|
||||||
|
|
||||||
void parse_args(int argc, char * argv[])
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 1; i < argc; i++) {
|
|
||||||
if (!strcmp(argv[i],"-a") && i<argc-1) aircraft_id = atoi(argv[++i]);
|
|
||||||
else if (!strcmp(argv[i],"-h")) goto l_help;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
|
|
||||||
l_help:
|
|
||||||
printf("Usage:\n");
|
|
||||||
printf(" %s <option> [<option>...]\n",argv[0]);
|
|
||||||
printf("Options:\n");
|
|
||||||
printf(" -a <int> aircraft id (default: %d)\n",DEFAULT_AC_ID);
|
|
||||||
printf(" -h display this help\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
<field name="ac_id" type="uint8"/>
|
|
||||||
<field name="h_mode" type="uint8" values="RATE|ATTITUDE|SPEED|POS"/>
|
|
||||||
<field name="v_mode" type="uint8" values="DIRECT|CLIMB|HEIGHT"/>
|
|
||||||
<field name="pad0" type="uint8"/>
|
|
||||||
<field name="pad1" type="uint8"/>
|
|
||||||
<field name="pad2" type="uint8"/>
|
|
||||||
<field name="v_sp" type="int32"/>
|
|
||||||
<field name="h_sp" type="int32[]"/>
|
|
||||||
*/
|
|
||||||
|
|
||||||
static gboolean periodic(gpointer data __attribute__ ((unused))) {
|
|
||||||
|
|
||||||
counter++;
|
|
||||||
|
|
||||||
uint8_t h_mode = FMS_H_MODE_ATTITUDE;
|
|
||||||
uint8_t v_mode = FMS_V_MODE_DIRECT;
|
|
||||||
int32_t pitch = FMS_ATTITUDE_OF_DEG(0);
|
|
||||||
int32_t roll = FMS_ATTITUDE_OF_DEG(STEP_VAL);
|
|
||||||
int32_t yaw = FMS_ATTITUDE_OF_DEG(0);
|
|
||||||
int32_t unused = 0;
|
|
||||||
if ((counter%(2*STEP_PERIOD)) >= STEP_PERIOD) roll = -roll;
|
|
||||||
|
|
||||||
IvySendMsg("dl BOOZ2_FMS_COMMAND %d %d %d %d d %d %d %d,%d,%d", aircraft_id, h_mode, v_mode, unused, unused, unused, unused, roll, pitch, yaw);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int main ( int argc, char** argv) {
|
|
||||||
|
|
||||||
GMainLoop *ml = g_main_loop_new(NULL, FALSE);
|
|
||||||
|
|
||||||
parse_args(argc, argv);
|
|
||||||
|
|
||||||
IvyInit ("IvyBooz2FmsAttStep", "IvyBooz2FmsAttStep READY", NULL, NULL, NULL, NULL);
|
|
||||||
IvyStart("127.255.255.255");
|
|
||||||
|
|
||||||
g_timeout_add(TIMEOUT_PERIOD, periodic, NULL);
|
|
||||||
|
|
||||||
g_main_loop_run(ml);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
/*
|
|
||||||
* fdm_step_position
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <glib.h>
|
|
||||||
#include <Ivy/ivy.h>
|
|
||||||
#include <Ivy/ivyglibloop.h>
|
|
||||||
|
|
||||||
#define TIMEOUT_PERIOD 100
|
|
||||||
#define DEFAULT_AC_ID 150
|
|
||||||
|
|
||||||
static int aircraft_id = DEFAULT_AC_ID;
|
|
||||||
static int counter;
|
|
||||||
|
|
||||||
static gboolean periodic(gpointer data __attribute__ ((unused)));
|
|
||||||
static void on_FMS_info(IvyClientPtr app, void *user_data, int argc, char *argv[]);
|
|
||||||
|
|
||||||
void parse_args(int argc, char * argv[])
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 1; i < argc; i++) {
|
|
||||||
if (!strcmp(argv[i],"-a") && i<argc-1) aircraft_id = atoi(argv[++i]);
|
|
||||||
else if (!strcmp(argv[i],"-h")) goto l_help;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
|
|
||||||
l_help:
|
|
||||||
printf("Usage:\n");
|
|
||||||
printf(" %s <option> [<option>...]\n",argv[0]);
|
|
||||||
printf("Options:\n");
|
|
||||||
printf(" -a <int> aircraft id (default: %d)\n",DEFAULT_AC_ID);
|
|
||||||
printf(" -h display this help\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void on_FMS_state(IvyClientPtr app, void *user_data, int argc, char *argv[]){
|
|
||||||
// guint ac_id = atoi(argv[0]);
|
|
||||||
// float estimator_phi = atof(argv[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define STEP_VAL 32
|
|
||||||
static gboolean periodic(gpointer data __attribute__ ((unused))) {
|
|
||||||
int roll, pitch;
|
|
||||||
counter++;
|
|
||||||
pitch = 0;
|
|
||||||
roll = STEP_VAL;
|
|
||||||
if ((counter%6) >=3) roll = -roll;
|
|
||||||
|
|
||||||
IvySendMsg("dl COMMANDS_RAW %d %d,%d", aircraft_id, roll, pitch);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int main ( int argc, char** argv) {
|
|
||||||
|
|
||||||
GMainLoop *ml = g_main_loop_new(NULL, FALSE);
|
|
||||||
|
|
||||||
parse_args(argc, argv);
|
|
||||||
|
|
||||||
IvyInit ("IvyFdmStep", "IvyFdmStep READY", NULL, NULL, NULL, NULL);
|
|
||||||
IvyStart("127.255.255.255");
|
|
||||||
|
|
||||||
g_timeout_add(TIMEOUT_PERIOD, periodic, NULL);
|
|
||||||
|
|
||||||
g_main_loop_run(ml);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
|
|
||||||
# Quiet compilation
|
|
||||||
Q=@
|
|
||||||
|
|
||||||
|
|
||||||
CC = gcc
|
|
||||||
CFLAGS=-g -O2 -Wall $(shell pkg-config gtk+-2.0 --cflags)
|
|
||||||
LDFLAGS=$(shell pkg-config gtk+-2.0 --libs) -lglibivy -lm -lgtkdatabox
|
|
||||||
|
|
||||||
ir_calib : main.c calibrator.c gui.c
|
|
||||||
$(CC) $(CFLAGS) -g -o $@ $^ $(LDFLAGS)
|
|
||||||
|
|
||||||
clean:
|
|
||||||
$(Q)rm -f *~ ir_calib
|
|
||||||
@@ -1,163 +0,0 @@
|
|||||||
#include "calibrator.h"
|
|
||||||
|
|
||||||
#include <Ivy/ivy.h>
|
|
||||||
#include <Ivy/ivyglibloop.h>
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <math.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#define DEG_OF_RAD(a) ((a)/M_PI*180.)
|
|
||||||
#define RAD_OF_DEG(a) ((a)*M_PI/180.)
|
|
||||||
#define NORM_ANGLE_RAD(a) { while ((a) < -M_PI ) (a) += 2 * M_PI; while ((a) > M_PI ) (a) -= 2 * M_PI; }
|
|
||||||
|
|
||||||
#define AC_ID 43
|
|
||||||
#define IR_ROLL_NEUTRAL 0.
|
|
||||||
#define IR_360_LATERAL_CORRECTION 1.
|
|
||||||
#define IR_360_VERTICAL_CORRECTION 1.
|
|
||||||
#define IR_CORRECTION_RIGHT 1.
|
|
||||||
#define IR_CORRECTION_LEFT 1.
|
|
||||||
|
|
||||||
#define DT 0.25
|
|
||||||
|
|
||||||
#define g 9.81
|
|
||||||
|
|
||||||
float est_airspeed;
|
|
||||||
float est_wind_dir;
|
|
||||||
float est_wind_speed;
|
|
||||||
float est_wind_east;
|
|
||||||
float est_wind_north;
|
|
||||||
|
|
||||||
float gnd_ir_phi;
|
|
||||||
float estimator_phi;
|
|
||||||
|
|
||||||
|
|
||||||
float gps_gs_east;
|
|
||||||
float gps_gs_north;
|
|
||||||
float gps_gs_angle;
|
|
||||||
float gps_gs_norm;
|
|
||||||
|
|
||||||
float gps_as_east;
|
|
||||||
float gps_as_north;
|
|
||||||
float gps_as_angle;
|
|
||||||
float gps_as_norm;
|
|
||||||
|
|
||||||
float gps_phi;
|
|
||||||
|
|
||||||
#define NB_POINTS 121
|
|
||||||
float estimator_phi_by_degres[NB_POINTS];
|
|
||||||
float alpha = 0.5;
|
|
||||||
|
|
||||||
static void on_Attitude(IvyClientPtr app, void *user_data, int argc, char *argv[]);
|
|
||||||
static void on_GPS(IvyClientPtr app, void *user_data, int argc, char *argv[]);
|
|
||||||
static void on_Wind(IvyClientPtr app, void *user_data, int argc, char *argv[]);
|
|
||||||
static void on_IrSensors(IvyClientPtr app, void *user_data, int argc, char *argv[]);
|
|
||||||
static void reset_average(void);
|
|
||||||
|
|
||||||
|
|
||||||
static void on_Attitude(IvyClientPtr app, void *user_data, int argc, char *argv[]){
|
|
||||||
//guint ac_id = atoi(argv[0]);
|
|
||||||
estimator_phi = RAD_OF_DEG(atof(argv[1]));
|
|
||||||
//g_message("attitude %d %f", ac_id, estimator_phi);
|
|
||||||
int gps_phi_deg = round(DEG_OF_RAD(gps_phi));
|
|
||||||
if (fabs(gps_phi_deg) <= NB_POINTS/2) {
|
|
||||||
unsigned int idx = gps_phi_deg + NB_POINTS/2;
|
|
||||||
estimator_phi_by_degres[idx] = (1-alpha) * estimator_phi_by_degres[idx] + alpha * DEG_OF_RAD(estimator_phi);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void on_GPS(IvyClientPtr app, void *user_data, int argc, char *argv[]){
|
|
||||||
unsigned int ac_id = atoi(argv[0]);
|
|
||||||
float course = atof(argv[4]);
|
|
||||||
float speed = atof(argv[6]);
|
|
||||||
|
|
||||||
gps_gs_norm = speed / 100.;
|
|
||||||
gps_gs_angle = RAD_OF_DEG(90. - course / 10.);
|
|
||||||
NORM_ANGLE_RAD( gps_gs_angle );
|
|
||||||
|
|
||||||
gps_gs_east = gps_gs_norm * cos(gps_gs_angle);
|
|
||||||
gps_gs_north = gps_gs_norm * sin(gps_gs_angle);
|
|
||||||
|
|
||||||
gps_as_east = gps_gs_east - est_wind_east;
|
|
||||||
gps_as_north = gps_gs_north - est_wind_north;
|
|
||||||
|
|
||||||
gps_as_angle = atan2(gps_as_north,gps_as_east);
|
|
||||||
gps_as_norm = sqrt(gps_as_east*gps_as_east + gps_as_north*gps_as_north);
|
|
||||||
|
|
||||||
static float old_psi = 0.;
|
|
||||||
float delta_psi = gps_as_angle - old_psi;
|
|
||||||
old_psi = gps_as_angle;
|
|
||||||
NORM_ANGLE_RAD(delta_psi);
|
|
||||||
|
|
||||||
/* tan(phi) = v^2 / (R*g) */
|
|
||||||
/* R = (V * dt) / dpsi */
|
|
||||||
|
|
||||||
if (fabs(delta_psi) < 1e-6)
|
|
||||||
delta_psi = copysign(1e-6, delta_psi);
|
|
||||||
|
|
||||||
float R = -gps_as_norm * DT / delta_psi;
|
|
||||||
|
|
||||||
gps_phi = atan(gps_as_norm * gps_as_norm / R / g);
|
|
||||||
|
|
||||||
printf("gps %d % 3.1f \t% 3.0f \t%.1f \t%.1f \t%.1f\n", ac_id, DEG_OF_RAD(delta_psi), R, DEG_OF_RAD(gps_phi), DEG_OF_RAD(estimator_phi), DEG_OF_RAD(gnd_ir_phi));
|
|
||||||
}
|
|
||||||
|
|
||||||
void on_Wind(IvyClientPtr app, void *user_data, int argc, char *argv[]){
|
|
||||||
//guint ac_id = atoi(argv[1]);
|
|
||||||
est_wind_dir = atof(argv[2]);
|
|
||||||
est_wind_speed = atof(argv[3]);
|
|
||||||
est_airspeed = atof(argv[4]);
|
|
||||||
|
|
||||||
float w_dir_rad =RAD_OF_DEG(270. - est_wind_dir);
|
|
||||||
NORM_ANGLE_RAD( w_dir_rad );
|
|
||||||
|
|
||||||
est_wind_east = est_wind_speed * cos( w_dir_rad );
|
|
||||||
est_wind_north = est_wind_speed * sin( w_dir_rad );
|
|
||||||
|
|
||||||
//g_message("wind %d %f %f %f", ac_id, w_dir, w_speed, ac_aspeed);
|
|
||||||
//g_message("wind %f %f %f", w_dir_rad, est_wind_east, est_wind_north);
|
|
||||||
}
|
|
||||||
|
|
||||||
void on_IrSensors(IvyClientPtr app, void *user_data, int argc, char *argv[]){
|
|
||||||
//guint ac_id = atoi(argv[0]);
|
|
||||||
float lateral = atof(argv[2]);
|
|
||||||
float vertical = atof(argv[3]);
|
|
||||||
|
|
||||||
float ir_roll = lateral * IR_360_LATERAL_CORRECTION;
|
|
||||||
float ir_top = vertical * IR_360_LATERAL_CORRECTION;
|
|
||||||
|
|
||||||
gnd_ir_phi = atan2(ir_roll, ir_top) - IR_ROLL_NEUTRAL;
|
|
||||||
|
|
||||||
if (gnd_ir_phi >= 0)
|
|
||||||
gnd_ir_phi *= IR_CORRECTION_RIGHT;
|
|
||||||
else
|
|
||||||
gnd_ir_phi *= IR_CORRECTION_LEFT;
|
|
||||||
|
|
||||||
// g_message("ir_sensors %d %.0f %.0f (%.1f)", ac_id, lateral, vertical, DEG_OF_RAD(phi));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void reset_average(void) {
|
|
||||||
|
|
||||||
int i;
|
|
||||||
for (i=0; i<NB_POINTS; i++) {
|
|
||||||
estimator_phi_by_degres[i] = i-NB_POINTS/2;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void calibrator_init(void) {
|
|
||||||
|
|
||||||
IvyInit ("IrCalib", "IrCalib READY", NULL, NULL, NULL, NULL);
|
|
||||||
IvyBindMsg(on_Attitude, NULL, "^(\\S*) ATTITUDE (\\S*) (\\S*) (\\S*)");
|
|
||||||
IvyBindMsg(on_GPS, NULL, "^(\\S*) GPS (\\S*) (\\S*) (\\S*) (\\S*) (\\S*) (\\S*) (\\S*) (\\S*) (\\S*) (\\S*)");
|
|
||||||
IvyBindMsg(on_Wind, NULL, "^(\\S*) WIND (\\S*) (\\S*) (\\S*) (\\S*) (\\S*)");
|
|
||||||
IvyBindMsg(on_IrSensors, NULL, "^(\\S*) IR_SENSORS (\\S*) (\\S*) (\\S*)");
|
|
||||||
IvyStart("127.255.255.255");
|
|
||||||
|
|
||||||
reset_average();
|
|
||||||
}
|
|
||||||
|
|
||||||
float* calibrator_get_values(void) {
|
|
||||||
return estimator_phi_by_degres;
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
#ifndef CALIBRATOR_H
|
|
||||||
#define CALIBRATOR_H
|
|
||||||
|
|
||||||
|
|
||||||
extern void calibrator_init(void);
|
|
||||||
extern float* calibrator_get_values(void);
|
|
||||||
|
|
||||||
#endif /* CALIBRATOR_H */
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
#include "gui.h"
|
|
||||||
|
|
||||||
#include <gtkdatabox.h>
|
|
||||||
#include <gtkdatabox_points.h>
|
|
||||||
#include <gtkdatabox_lines.h>
|
|
||||||
#include <gtkdatabox_bars.h>
|
|
||||||
#include <gtkdatabox_grid.h>
|
|
||||||
#include <gtkdatabox_cross_simple.h>
|
|
||||||
#include <gtkdatabox_markers.h>
|
|
||||||
|
|
||||||
#define NB_POINTS 121
|
|
||||||
|
|
||||||
gfloat *X;
|
|
||||||
gfloat *Y1;
|
|
||||||
gfloat *Y2;
|
|
||||||
|
|
||||||
static GtkWidget* databox;
|
|
||||||
|
|
||||||
GtkWidget* gui_init(void) {
|
|
||||||
|
|
||||||
GtkWidget *window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
|
||||||
gtk_widget_set_size_request (window, 640, 400);
|
|
||||||
|
|
||||||
GtkWidget *vbox1 = gtk_vbox_new (FALSE, 0);
|
|
||||||
gtk_container_add (GTK_CONTAINER (window), vbox1);
|
|
||||||
|
|
||||||
GtkWidget *frame = gtk_frame_new ("Foo");
|
|
||||||
gtk_container_set_border_width (GTK_CONTAINER (frame), 10);
|
|
||||||
gtk_box_pack_start (GTK_BOX (vbox1), frame, TRUE, TRUE, 0);
|
|
||||||
|
|
||||||
databox = gtk_databox_new ();
|
|
||||||
gtk_container_add (GTK_CONTAINER (frame), databox );
|
|
||||||
|
|
||||||
X = g_new0 (gfloat, NB_POINTS);
|
|
||||||
Y1 = g_new0 (gfloat, NB_POINTS);
|
|
||||||
Y2 = g_new0 (gfloat, NB_POINTS);
|
|
||||||
guint i;
|
|
||||||
for (i=0; i<NB_POINTS; i++){
|
|
||||||
X[i] = (gfloat)i - NB_POINTS/2;
|
|
||||||
Y1[i] = (gfloat)i -NB_POINTS/2;
|
|
||||||
Y2[i] = (gfloat)i -NB_POINTS/2;
|
|
||||||
}
|
|
||||||
|
|
||||||
GdkColor cblack = {0, 0, 0, 0};
|
|
||||||
GdkColor cred = {0, 65535, 0, 0};
|
|
||||||
|
|
||||||
GtkDataboxGraph *graph1 = gtk_databox_lines_new (NB_POINTS, X, Y1, &cblack, 2);
|
|
||||||
gtk_databox_graph_add (GTK_DATABOX (databox), graph1);
|
|
||||||
|
|
||||||
GtkDataboxGraph *graph2 = gtk_databox_lines_new (NB_POINTS, X, Y2, &cred, 2);
|
|
||||||
gtk_databox_graph_add (GTK_DATABOX (databox), graph2);
|
|
||||||
|
|
||||||
GtkDataboxGraph *grid = gtk_databox_grid_new (11, 11, &cblack, 1);
|
|
||||||
gtk_databox_graph_add (GTK_DATABOX (databox), grid);
|
|
||||||
|
|
||||||
gtk_databox_auto_rescale (GTK_DATABOX(databox), 0.);
|
|
||||||
|
|
||||||
gtk_widget_show_all(window);
|
|
||||||
return window;
|
|
||||||
}
|
|
||||||
|
|
||||||
void gui_update(gfloat* values) {
|
|
||||||
guint i;
|
|
||||||
for (i=0; i<NB_POINTS; i++){
|
|
||||||
Y2[i] = values[i];
|
|
||||||
}
|
|
||||||
gtk_databox_auto_rescale (GTK_DATABOX(databox), 0.);
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
#ifndef GUI_H
|
|
||||||
#define GUI_H
|
|
||||||
|
|
||||||
#include <gtk/gtk.h>
|
|
||||||
|
|
||||||
extern GtkWidget* gui_init(void);
|
|
||||||
|
|
||||||
extern void gui_update(gfloat* values);
|
|
||||||
|
|
||||||
#endif /* GUI_H */
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
#include <glib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <math.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
|
|
||||||
#include "calibrator.h"
|
|
||||||
#include "gui.h"
|
|
||||||
|
|
||||||
gboolean timeout_callback(gpointer data) {
|
|
||||||
|
|
||||||
float* values = calibrator_get_values();
|
|
||||||
gui_update(values);
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int main ( int argc, char** argv) {
|
|
||||||
|
|
||||||
// GMainLoop *ml = g_main_loop_new(NULL, FALSE);
|
|
||||||
|
|
||||||
gtk_init(&argc, &argv);
|
|
||||||
|
|
||||||
g_timeout_add(500, timeout_callback, NULL);
|
|
||||||
|
|
||||||
calibrator_init();
|
|
||||||
|
|
||||||
gui_init();
|
|
||||||
|
|
||||||
//g_main_loop_run(ml);
|
|
||||||
gtk_main();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
#
|
|
||||||
# Makefile
|
|
||||||
#
|
|
||||||
|
|
||||||
# Quiet compilation
|
|
||||||
Q=@
|
|
||||||
|
|
||||||
APP = i2c_usb
|
|
||||||
|
|
||||||
all: $(APP)
|
|
||||||
|
|
||||||
clean:
|
|
||||||
$(Q)rm -f $(APP)
|
|
||||||
|
|
||||||
$(APP): $(APP).c
|
|
||||||
$(CC) -Wall -o $@ $(APP).c -lusb
|
|
||||||
|
|
||||||
install:
|
|
||||||
install $(APP) $(DESTDIR)/usr/bin
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,52 +0,0 @@
|
|||||||
i2c-tiny-usb test application - http://www.harbaum.org/till/i2c_tiny_usb
|
|
||||||
------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Adapted to Melexis 90614 IR sensors.
|
|
||||||
|
|
||||||
This simple test application is meant to demonstrate libusb
|
|
||||||
interfacing to the i2c-tiny-usb interface.
|
|
||||||
|
|
||||||
This is no useful application, if you are only interesting in
|
|
||||||
using the i2c-tiny-usb interface in your linux box please
|
|
||||||
use the kernel driver.
|
|
||||||
|
|
||||||
Linux
|
|
||||||
-----
|
|
||||||
|
|
||||||
This demo application has been developed under and for linux. Just
|
|
||||||
make sure you have libusb installed. To use this program just
|
|
||||||
compile by typing "make" and run the resulting i2c_usb.
|
|
||||||
|
|
||||||
Be sure that the i2c-tiny-usb kernel driver is not loaded while
|
|
||||||
running the test application. Otherwise the test application will
|
|
||||||
fail with the follwing error message:
|
|
||||||
|
|
||||||
USB error: could not claim interface 0: Device or resource busy
|
|
||||||
|
|
||||||
This is due to the fact that no two drivers may access the interface
|
|
||||||
at the same time.
|
|
||||||
|
|
||||||
Windows
|
|
||||||
-------
|
|
||||||
|
|
||||||
This program can be compiled for windows. This has been tested
|
|
||||||
under Linux using xmingw and the windows port of libusb
|
|
||||||
(see http://libusb-win32.sourceforge.net). To install the
|
|
||||||
driver plug the device in and install the driver from
|
|
||||||
the win directory. Then run testapp/i2c_usb.exe
|
|
||||||
|
|
||||||
This program may also be compiled under windows using cygwin or
|
|
||||||
mingw (which is part of cygwin). In order to use cygwin simply
|
|
||||||
copy usb.h win32-linusb to /cygwin/usr/include and libusb.a to
|
|
||||||
/cygwin/lib and do a "make -f Makefile.cygwin". Don't forget to
|
|
||||||
distribute /cygwin/bin/cygwin1.dll with your file to allow it to
|
|
||||||
run in non-cygwin environments as well. No dll is required when using
|
|
||||||
mingw. In that case copy usb.h to /cygwin/usr/include/mingw and
|
|
||||||
libusb.a to /cygwin/lib/mingw. Finally do a "make -f Makefile.mingw".
|
|
||||||
|
|
||||||
MacOS X
|
|
||||||
-------
|
|
||||||
|
|
||||||
The program can be compiled under MacOS as well. The fink version
|
|
||||||
of linusb has to be installed and a simple "make -f Makefile.macos"
|
|
||||||
will build the native MacOS X version.
|
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
/*
|
|
||||||
http://modestmaps.mapstraction.com/trac/wiki/TileNamingConventions
|
|
||||||
http://www.maptiler.org/google-maps-coordinates-tile-bounds-projection/
|
|
||||||
http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames3
|
|
||||||
|
|
||||||
gcc osm.c -lm -Wall -o osm
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
int long2tile(double lon, int z)
|
|
||||||
{
|
|
||||||
return (int)(floor((lon + 180.0) / 360.0 * pow(2.0, z)));
|
|
||||||
}
|
|
||||||
|
|
||||||
int lat2tile(double lat, int z)
|
|
||||||
{
|
|
||||||
return (int)(floor((1.0 - log( tan(lat * M_PI/180.0) + 1.0 / cos(lat * M_PI/180.0)) / M_PI) / 2.0 * pow(2.0, z)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void gm_quadtree(int x, int y, int z, char *buffer)
|
|
||||||
{
|
|
||||||
static const char *const quadrant = "qrts";
|
|
||||||
int i;
|
|
||||||
char *ptr = buffer;
|
|
||||||
|
|
||||||
*ptr++ = 't';
|
|
||||||
for (i = z-1; i >= 0; i--)
|
|
||||||
{
|
|
||||||
int xbit = (x >> i) & 1;
|
|
||||||
int ybit = (y >> i) & 1;
|
|
||||||
*ptr++ = quadrant[xbit + 2 * ybit];
|
|
||||||
}
|
|
||||||
*ptr++ = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
void ms_quadtree(int x, int y, int z, char *buffer)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
char *ptr = buffer;
|
|
||||||
|
|
||||||
for (i = z; i > 0; i--)
|
|
||||||
{
|
|
||||||
int mask = 1 << (i - 1);
|
|
||||||
char digit = '0';
|
|
||||||
if ((x & mask) != 0)
|
|
||||||
{
|
|
||||||
digit+=1;
|
|
||||||
}
|
|
||||||
if ((y & mask) != 0)
|
|
||||||
{
|
|
||||||
digit+=2;
|
|
||||||
}
|
|
||||||
*ptr++ = digit;
|
|
||||||
}
|
|
||||||
*ptr++ = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(void)
|
|
||||||
{
|
|
||||||
int x, y, z = 14;
|
|
||||||
double lat = 52.26483, lon = 9.99394;
|
|
||||||
char ms_qkey[32];
|
|
||||||
char gm_qkey[32];
|
|
||||||
|
|
||||||
x = long2tile(lon, z);
|
|
||||||
y = lat2tile(lat, z);
|
|
||||||
ms_quadtree(x, y, z, ms_qkey);
|
|
||||||
gm_quadtree(x, y, z, gm_qkey);
|
|
||||||
|
|
||||||
printf("http://tile.openstreetmap.org/%d/%d/%d.png\n", z, x, y);
|
|
||||||
printf("http://khm0.google.com/kh/v=45&x=%d&s=&y=%d&z=%d\n", x, y, z);
|
|
||||||
// printf("http://kh.google.com/kh?v=3&t=%s\n", gm_qkey);
|
|
||||||
// printf("http://mt1.google.com/mt/v=ap.95&hl=en&x=%d&y=%d&z=%d&s=G\n", x, y, z);
|
|
||||||
printf("http://a0.ortho.tiles.virtualearth.net/tiles/a%s.jpeg?g=%d\n", ms_qkey, z+32);
|
|
||||||
printf("http://r0.ortho.tiles.virtualearth.net/tiles/r%s.png?g=%d\n", ms_qkey, z+32);
|
|
||||||
|
|
||||||
return(0);
|
|
||||||
};
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
# Quiet compilation
|
|
||||||
Q=@
|
|
||||||
|
|
||||||
CC = gcc
|
|
||||||
CFLAGS=-g -O2 -Wall $(shell pkg-config gtk+-2.0 --cflags) -I../../../var/MB
|
|
||||||
LDFLAGS=$(shell pkg-config gtk+-2.0 --libs) -s -lglibivy
|
|
||||||
|
|
||||||
motor_bench : main.c
|
|
||||||
$(CC) $(CFLAGS) -g -o $@ $^ $(LDFLAGS)
|
|
||||||
|
|
||||||
# -lgtkdatabox
|
|
||||||
|
|
||||||
LOG=mb_log.txt
|
|
||||||
|
|
||||||
plot_test:
|
|
||||||
scilab -f test.sce -args $(LOG)
|
|
||||||
|
|
||||||
clean:
|
|
||||||
$(Q)rm -f *~ motor_bench
|
|
||||||
|
|
||||||
Binary file not shown.
@@ -1,56 +0,0 @@
|
|||||||
clear();
|
|
||||||
getf('mb_utils.sci');
|
|
||||||
|
|
||||||
filename = "data/steps_stout_aero_geared.txt";
|
|
||||||
|
|
||||||
[time, throttle, rpm, amp, thrust, torque] = read_mb_log(filename);
|
|
||||||
|
|
||||||
|
|
||||||
// design an iir low pass with cutoff freq at 125Hz
|
|
||||||
hz=iir(3,'lp','ellip',[0.5 0.5],[.01 .01]);
|
|
||||||
|
|
||||||
//[hzm,fr]=frmag(hz,256);
|
|
||||||
//plot2d(fr',hzm',3)
|
|
||||||
|
|
||||||
[rpm_lp] = rtitr(hz(2), hz(3), rpm);
|
|
||||||
|
|
||||||
|
|
||||||
//if 0
|
|
||||||
xbasc();
|
|
||||||
subplot(2,1,1)
|
|
||||||
xtitle('Throttle');
|
|
||||||
plot(time(30:length(time)), throttle(30:length(throttle)), 'b-');
|
|
||||||
subplot(2,1,2)
|
|
||||||
plot(time(30:length(time)), rpm(30:length(rpm)), 'r-');
|
|
||||||
plot(time(30:length(time)), rpm_lp(30:length(rpm_lp)), 'g-');
|
|
||||||
//end
|
|
||||||
|
|
||||||
s_avg = 30;
|
|
||||||
e_avg = 118;
|
|
||||||
rpm0 = mean(rpm(s_avg:e_avg));
|
|
||||||
|
|
||||||
plot(time(s_avg:e_avg), rpm0*ones(1,e_avg - s_avg + 1), 'b-');
|
|
||||||
|
|
||||||
my_kv = 100000;
|
|
||||||
my_taukq = - 0.0003313; // plain wrong it seems :(
|
|
||||||
my_tau = 0.3; //
|
|
||||||
my_kq = my_taukq / my_tau; //
|
|
||||||
|
|
||||||
|
|
||||||
time_ode = time(s_avg:length(time));
|
|
||||||
u_ode = throttle(s_avg:length(throttle));
|
|
||||||
|
|
||||||
|
|
||||||
function rpm_dot = my_mot_ode(t, rpm)
|
|
||||||
if ((t >= 389.7960)& (t < 390.7960))
|
|
||||||
thr = 0.7;
|
|
||||||
else
|
|
||||||
thr = 0.6;
|
|
||||||
end
|
|
||||||
rpm_dot = mot_ode(my_tau, my_kq, my_kv, thr);
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
rpm_sim = ode([rpm0], time(1), time_ode, my_mot_ode);
|
|
||||||
|
|
||||||
plot(time_ode, rpm_sim, 'r-');
|
|
||||||
@@ -1,108 +0,0 @@
|
|||||||
clear();
|
|
||||||
getf('mb_utils.sci');
|
|
||||||
|
|
||||||
rank=[];
|
|
||||||
time_s=[];
|
|
||||||
time_r=[];
|
|
||||||
throttle_raw=[];
|
|
||||||
tacho_raw=[];
|
|
||||||
|
|
||||||
u=mopen('data/xxx_prbs.txt','r');
|
|
||||||
while meof(u) == 0,
|
|
||||||
line = mgetl(u, 1);
|
|
||||||
if strindex(line, '#') ~= 1 & length(line) ~= 0,
|
|
||||||
[nb_scan, _rank, _time_s, _time_r, _throttle_raw, _tacho_raw] = msscanf(1, line, '%x %x %x %x %x');
|
|
||||||
if nb_scan == 5,
|
|
||||||
rank = [rank _rank];
|
|
||||||
time_s = [time_s _time_s];
|
|
||||||
time_r = [time_r _time_r];
|
|
||||||
throttle_raw = [throttle_raw _throttle_raw];
|
|
||||||
tacho_raw = [tacho_raw _tacho_raw];
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
mclose(u);
|
|
||||||
|
|
||||||
|
|
||||||
// extract experiment
|
|
||||||
//EXPE_LEN = 4096;
|
|
||||||
EXPE_LEN = 100;
|
|
||||||
EXPE_START = 41;
|
|
||||||
rank = rank(EXPE_START:EXPE_START+EXPE_LEN);
|
|
||||||
time_s = time_s(EXPE_START:EXPE_START+EXPE_LEN);
|
|
||||||
time_r = time_r(EXPE_START:EXPE_START+EXPE_LEN);
|
|
||||||
throttle_raw = throttle_raw(EXPE_START:EXPE_START+EXPE_LEN);
|
|
||||||
tacho_raw = tacho_raw(EXPE_START:EXPE_START+EXPE_LEN);
|
|
||||||
|
|
||||||
// compute time
|
|
||||||
TICK_PER_S = 15625;
|
|
||||||
time = time_s + time_r / TICK_PER_S;
|
|
||||||
DT = (time(length(time)) - time(1)) / (length(time) - 1)
|
|
||||||
F_EC = 1 / DT
|
|
||||||
|
|
||||||
// normalise throttle
|
|
||||||
MAX_PPRZ = 9600;
|
|
||||||
throttle = throttle_raw / MAX_PPRZ;
|
|
||||||
|
|
||||||
// compute rpms
|
|
||||||
TICK_PER_ROTATION = 36;
|
|
||||||
rpm = tacho_raw / DT / TICK_PER_ROTATION * 60;
|
|
||||||
|
|
||||||
// integrate ODE
|
|
||||||
//kv0 = 100000;
|
|
||||||
kv0 = 22000;
|
|
||||||
//taukq = 0.0003313; //
|
|
||||||
taukq = 0.00001; //
|
|
||||||
//tau0 = 0.3; //
|
|
||||||
tau0 = 0.1; //
|
|
||||||
kq0 = taukq / tau0; //
|
|
||||||
|
|
||||||
rpm0 = rpm(1);
|
|
||||||
|
|
||||||
//idx = 1;
|
|
||||||
function rpm_dot = prbs_mot_ode(t, rpm)
|
|
||||||
idx=1;
|
|
||||||
while (time(idx) < t & idx < length(throttle)), idx=idx+1, end
|
|
||||||
// printf('%f %d %f\n', t, idx, time(idx));
|
|
||||||
rpm_dot = mot_ode(my_tau, my_kq, my_kv, throttle(idx), rpm);
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
p0 = [tau0; kv0; kq0];
|
|
||||||
|
|
||||||
|
|
||||||
function e = err_prbs(p,z)
|
|
||||||
my_tau = p(1);
|
|
||||||
my_kv = p(2);
|
|
||||||
my_kq = p(3);
|
|
||||||
rpm_sim = ode([rpm0], time(1), time, prbs_mot_ode);
|
|
||||||
_diff = rpm_sim - rpm;
|
|
||||||
sq_diff = _diff^2;
|
|
||||||
e = sum(sq_diff);
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
if 0
|
|
||||||
my_tau = tau0;
|
|
||||||
my_kv = kv0;
|
|
||||||
my_kq = kq0;
|
|
||||||
rpm_sim = ode([rpm0], time(1), time, prbs_mot_ode);
|
|
||||||
else
|
|
||||||
Z = [ 1; 1]; //unused...
|
|
||||||
[p, err] = datafit(err_prbs, Z, p0)
|
|
||||||
my_tau = p(1);
|
|
||||||
my_kv = p(2);
|
|
||||||
my_kq = p(3);
|
|
||||||
rpm_sim = ode([rpm0], time(1), time, prbs_mot_ode);
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
xbasc();
|
|
||||||
subplot(2,1,1);
|
|
||||||
xtitle('Throttle');
|
|
||||||
plot(time, throttle, 'b-');
|
|
||||||
|
|
||||||
subplot(2,1,2);
|
|
||||||
plot(time, rpm, 'r-');
|
|
||||||
plot(time, rpm_sim, 'b-');
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
clear();
|
|
||||||
getf('mb_utils.sci');
|
|
||||||
|
|
||||||
load('averaged_ramp_geared.dat','av_throttle','av_rpm')
|
|
||||||
|
|
||||||
// extract only data around operating point
|
|
||||||
//i_s = 20;
|
|
||||||
//i_e = 90;
|
|
||||||
i_s = 5;
|
|
||||||
i_e = 90;
|
|
||||||
t_part = av_throttle(i_s:i_e);
|
|
||||||
r_part = av_rpm(i_s:i_e);
|
|
||||||
|
|
||||||
// tau_kq kv dv
|
|
||||||
p0=[0.00001; 20000];
|
|
||||||
Z = [r_part; t_part];
|
|
||||||
//[p, err] = datafit(err_mot_lin, Z, p0);
|
|
||||||
|
|
||||||
[p, err] = datafit(err_mot_ric, Z, p0)
|
|
||||||
//p = p0;
|
|
||||||
|
|
||||||
xbasc();
|
|
||||||
//subplot(3,1,1);
|
|
||||||
xtitle('Rpms vs Throttle');
|
|
||||||
plot2d(av_throttle,av_rpm);
|
|
||||||
plot2d(t_part,r_part, 4);
|
|
||||||
|
|
||||||
|
|
||||||
r_fit = [];
|
|
||||||
for i=1:length(av_throttle)
|
|
||||||
// r_fit = [r_fit mot_lin(av_throttle(i), p)];
|
|
||||||
r_fit = [r_fit mot_ric_stat(av_throttle(i), p)];
|
|
||||||
end
|
|
||||||
|
|
||||||
plot2d(av_throttle,r_fit, 3);
|
|
||||||
@@ -1,445 +0,0 @@
|
|||||||
#include <gtk/gtk.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <math.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include <Ivy/ivy.h>
|
|
||||||
#include <Ivy/ivyglibloop.h>
|
|
||||||
|
|
||||||
#define ASTECH 1
|
|
||||||
|
|
||||||
#include "tuning.h"
|
|
||||||
|
|
||||||
//#include "sliding_plot.h"
|
|
||||||
|
|
||||||
#define MB_MODES_IDLE 0
|
|
||||||
#define MB_MODES_MANUAL 1
|
|
||||||
#define MB_MODES_RAMP 2
|
|
||||||
#define MB_MODES_STEP 3
|
|
||||||
#define MB_MODES_PRBS 4
|
|
||||||
#define MB_MODES_SINE 5
|
|
||||||
#define MB_MODES_FIXED_RPM 6
|
|
||||||
|
|
||||||
#define AS_MOT_FRONT 0
|
|
||||||
#define AS_MOT_BACK 1
|
|
||||||
#define AS_MOT_LEFT 2
|
|
||||||
#define AS_MOT_RIGHT 3
|
|
||||||
|
|
||||||
#define AS_CMD_TEST_ADDR 1
|
|
||||||
#define AS_CMD_REVERSE 2
|
|
||||||
#define AS_CMD_SET_ADDR 3
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const guint mb_id = 158;
|
|
||||||
|
|
||||||
struct motor_bench_state {
|
|
||||||
guint mode;
|
|
||||||
double time;
|
|
||||||
double throttle;
|
|
||||||
double rpms;
|
|
||||||
double amps;
|
|
||||||
double thrust;
|
|
||||||
double torque;
|
|
||||||
double av_rpm;
|
|
||||||
double av_throttle;
|
|
||||||
double av_thrust;
|
|
||||||
double av_amps;
|
|
||||||
GIOChannel* log_channel;
|
|
||||||
GIOChannel* log_channel_static;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct motor_bench_gui {
|
|
||||||
GtkWidget* lab_time;
|
|
||||||
GtkWidget* lab_throttle;
|
|
||||||
GtkWidget* lab_rpms;
|
|
||||||
GtkWidget* lab_amps;
|
|
||||||
GtkWidget* lab_thrust;
|
|
||||||
GtkWidget* lab_torque;
|
|
||||||
GtkWidget* entry_log;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void on_mode_changed (GtkRadioButton *radiobutton, gpointer user_data);
|
|
||||||
static void on_MOTOR_BENCH_STATUS(IvyClientPtr app, void *user_data, int argc, char *argv[]);
|
|
||||||
static gboolean timeout_callback(gpointer data);
|
|
||||||
static void on_log_button_toggled (GtkWidget *widget, gpointer data);
|
|
||||||
|
|
||||||
static void on_as_test_button_clicked (GtkWidget *widget, gpointer data);
|
|
||||||
static void on_as_reverse_button_clicked (GtkWidget *widget, gpointer data);
|
|
||||||
static void on_as_addr_changed (GtkRadioButton *radiobutton, gpointer user_data);
|
|
||||||
|
|
||||||
|
|
||||||
static GtkWidget* build_gui ( void );
|
|
||||||
|
|
||||||
static struct motor_bench_state mb_state;
|
|
||||||
static struct motor_bench_gui mb_gui;
|
|
||||||
|
|
||||||
static void on_mode_changed (GtkRadioButton *radiobutton, gpointer user_data) {
|
|
||||||
if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radiobutton)))
|
|
||||||
return;
|
|
||||||
guint mode = (guint)user_data;
|
|
||||||
IvySendMsg("dl DL_SETTING %d %d %d", mb_id, PPRZ_MB_MODES_MODE, mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
void on_scale_value_changed (GtkScale *scale, gpointer user_data) {
|
|
||||||
gfloat cf = gtk_range_get_value(GTK_RANGE(scale));
|
|
||||||
gint c = round(cf);
|
|
||||||
g_message("foo %d %f", user_data, c);
|
|
||||||
IvySendMsg("ME RAW_DATALINK 16 SETTING;%d;0;%d", (gint)user_data, c);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
static void on_MOTOR_BENCH_STATUS(IvyClientPtr app, void *user_data, int argc, char *argv[]){
|
|
||||||
guint time_ticks = atoi(argv[0]);
|
|
||||||
double throttle = atof(argv[1]);
|
|
||||||
double rpm = atof(argv[2]);
|
|
||||||
double amp = atof(argv[3]);
|
|
||||||
double thrust = atof(argv[4]);
|
|
||||||
double torque = atof(argv[5]);
|
|
||||||
guint time_sec = atoi(argv[6]);
|
|
||||||
guint mode = atoi(argv[7]);
|
|
||||||
mb_state.mode = mode;
|
|
||||||
mb_state.time = (double)time_sec + (double)time_ticks/15000000.;
|
|
||||||
mb_state.throttle = throttle;
|
|
||||||
mb_state.rpms = rpm;
|
|
||||||
mb_state.amps = amp;
|
|
||||||
mb_state.thrust = thrust;
|
|
||||||
mb_state.torque = torque;
|
|
||||||
if (mb_state.log_channel) {
|
|
||||||
GString* str = g_string_sized_new(256);
|
|
||||||
g_string_printf(str, "%.4f %.3f %.0f %.1f %.1f %.1f\n", mb_state.time, mb_state.throttle, mb_state.rpms, mb_state.amps, mb_state.thrust, mb_state.torque);
|
|
||||||
gsize b_writen;
|
|
||||||
GError* my_err = NULL;
|
|
||||||
GIOStatus stat = g_io_channel_write_chars(mb_state.log_channel,str->str, str->len, &b_writen, &my_err);
|
|
||||||
g_string_free(str, TRUE);
|
|
||||||
}
|
|
||||||
// g_message("foo %f %f %f %f %d", mb_state.time, throttle, rpm, amp, mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void on_MOTOR_BENCH_STATIC(IvyClientPtr app, void *user_data, int argc, char *argv[]){
|
|
||||||
mb_state.av_rpm = atof(argv[0]);
|
|
||||||
mb_state.av_thrust = atof(argv[1]);
|
|
||||||
mb_state.av_amps = atof(argv[2]);
|
|
||||||
mb_state.av_throttle = atof(argv[3]);
|
|
||||||
|
|
||||||
if (mb_state.log_channel_static) {
|
|
||||||
GString* str = g_string_sized_new(256);
|
|
||||||
g_string_printf(str, "%0f %.3f %.2f %.1f\n", mb_state.av_throttle, mb_state.av_rpm, mb_state.av_amps, mb_state.av_thrust);
|
|
||||||
gsize b_writen;
|
|
||||||
GError* my_err = NULL;
|
|
||||||
GIOStatus stat = g_io_channel_write_chars(mb_state.log_channel_static,str->str, str->len, &b_writen, &my_err);
|
|
||||||
g_string_free(str, TRUE);
|
|
||||||
}
|
|
||||||
g_message("in_static %f %f %f %f", mb_state.av_throttle, mb_state.av_rpm, mb_state.av_amps, mb_state.av_thrust);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static gboolean timeout_callback(gpointer data) {
|
|
||||||
GString* str = g_string_sized_new(64);
|
|
||||||
g_string_printf(str, "%.2f s", mb_state.time);
|
|
||||||
gtk_label_set_text(GTK_LABEL(mb_gui.lab_time), str->str);
|
|
||||||
g_string_printf(str, "%.2f %%", mb_state.throttle*100.);
|
|
||||||
gtk_label_set_text(GTK_LABEL(mb_gui.lab_throttle), str->str);
|
|
||||||
g_string_printf(str, "%.0f rpms", mb_state.rpms);
|
|
||||||
gtk_label_set_text(GTK_LABEL(mb_gui.lab_rpms), str->str);
|
|
||||||
g_string_printf(str, "%.1f a", mb_state.amps);
|
|
||||||
gtk_label_set_text(GTK_LABEL(mb_gui.lab_amps), str->str);
|
|
||||||
g_string_printf(str, "%.1f g", mb_state.thrust);
|
|
||||||
gtk_label_set_text(GTK_LABEL(mb_gui.lab_thrust), str->str);
|
|
||||||
g_string_printf(str, "%.1f g", mb_state.torque);
|
|
||||||
gtk_label_set_text(GTK_LABEL(mb_gui.lab_torque), str->str);
|
|
||||||
g_string_free(str, TRUE);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void on_log_button_toggled (GtkWidget *widget, gpointer data) {
|
|
||||||
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))) {
|
|
||||||
gtk_editable_set_editable( GTK_EDITABLE(mb_gui.entry_log), FALSE );
|
|
||||||
const gchar *log_file_name = gtk_entry_get_text (GTK_ENTRY (mb_gui.entry_log));
|
|
||||||
GError* my_err = NULL;
|
|
||||||
mb_state.log_channel = g_io_channel_new_file (log_file_name, "w", &my_err);
|
|
||||||
GString* static_name = g_string_sized_new(128);
|
|
||||||
g_string_printf(static_name,"%s%s", log_file_name, "_static");
|
|
||||||
mb_state.log_channel_static = g_io_channel_new_file (static_name->str, "w", &my_err);
|
|
||||||
g_string_free(static_name, TRUE);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
gtk_editable_set_editable( GTK_EDITABLE(mb_gui.entry_log), TRUE );
|
|
||||||
if (mb_state.log_channel) {
|
|
||||||
g_io_channel_close(mb_state.log_channel);
|
|
||||||
g_io_channel_close(mb_state.log_channel_static);
|
|
||||||
mb_state.log_channel = NULL;
|
|
||||||
mb_state.log_channel_static = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void on_as_test_button_clicked (GtkWidget *widget, gpointer data) {
|
|
||||||
#ifdef ASTECH
|
|
||||||
IvySendMsg("dl DL_SETTING %d %d %d", mb_id, PPRZ_MB_TWI_CONTROLLER_ASCTECH_COMMAND_TYPE, AS_CMD_TEST_ADDR);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static void on_as_reverse_button_clicked (GtkWidget *widget, gpointer data) {
|
|
||||||
#ifdef ASTECH
|
|
||||||
IvySendMsg("dl DL_SETTING %d %d %d", mb_id, PPRZ_MB_TWI_CONTROLLER_ASCTECH_COMMAND_TYPE, AS_CMD_REVERSE);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void on_as_addr_changed (GtkRadioButton *radiobutton, gpointer user_data) {
|
|
||||||
#ifdef ASTECH
|
|
||||||
if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radiobutton)))
|
|
||||||
return;
|
|
||||||
guint new_addr = (guint)user_data;
|
|
||||||
IvySendMsg("dl DL_SETTING %d %d %d", mb_id, PPRZ_MB_TWI_CONTROLLER_ASCTECH_ADDR, new_addr);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int main (int argc, char** argv) {
|
|
||||||
|
|
||||||
gtk_init(&argc, &argv);
|
|
||||||
|
|
||||||
GtkWidget* window = build_gui();
|
|
||||||
gtk_widget_show_all(window);
|
|
||||||
|
|
||||||
IvyInit ("MotorBench", "MotorBench READY", NULL, NULL, NULL, NULL);
|
|
||||||
IvyBindMsg(on_MOTOR_BENCH_STATUS, NULL, "^\\S* MOTOR_BENCH_STATUS (\\S*) (\\S*) (\\S*) (\\S*) (\\S*) (\\S*) (\\S*) (\\S*)");
|
|
||||||
IvyBindMsg(on_MOTOR_BENCH_STATIC, NULL, "^\\S* MOTOR_BENCH_STATIC (\\S*) (\\S*) (\\S*) (\\S*)");
|
|
||||||
IvyStart("127.255.255.255");
|
|
||||||
|
|
||||||
g_timeout_add(40, timeout_callback, NULL);
|
|
||||||
|
|
||||||
mb_state.log_channel = NULL;
|
|
||||||
|
|
||||||
gtk_main();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static GtkWidget* build_gui ( void ) {
|
|
||||||
|
|
||||||
GtkWidget *window1;
|
|
||||||
GtkWidget *vbox1;
|
|
||||||
|
|
||||||
|
|
||||||
window1 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
|
||||||
gtk_window_set_title (GTK_WINDOW (window1), "motor_bench");
|
|
||||||
|
|
||||||
vbox1 = gtk_vbox_new (FALSE, 0);
|
|
||||||
gtk_container_add (GTK_CONTAINER (window1), vbox1);
|
|
||||||
|
|
||||||
GtkWidget* hbox1 = gtk_hbox_new (FALSE, 0);
|
|
||||||
gtk_box_pack_start (GTK_BOX (vbox1), hbox1, TRUE, TRUE, 0);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Modes
|
|
||||||
//
|
|
||||||
GtkWidget *mode_frame = gtk_frame_new ("Mode");
|
|
||||||
gtk_container_set_border_width (GTK_CONTAINER (mode_frame), 10);
|
|
||||||
gtk_box_pack_start (GTK_BOX (hbox1), mode_frame, TRUE, TRUE, 0);
|
|
||||||
|
|
||||||
GtkWidget* vbox2 = gtk_vbox_new (FALSE, 0);
|
|
||||||
gtk_container_add (GTK_CONTAINER (mode_frame), vbox2);
|
|
||||||
|
|
||||||
GSList *rb_mode_group = NULL;
|
|
||||||
GtkWidget* rb_idle = gtk_radio_button_new_with_mnemonic (NULL, "idle");
|
|
||||||
gtk_box_pack_start (GTK_BOX (vbox2), rb_idle, TRUE, TRUE, 0);
|
|
||||||
gtk_radio_button_set_group (GTK_RADIO_BUTTON (rb_idle), rb_mode_group);
|
|
||||||
rb_mode_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (rb_idle));
|
|
||||||
GtkWidget* rb_manual = gtk_radio_button_new_with_mnemonic (NULL, "manual");
|
|
||||||
gtk_box_pack_start (GTK_BOX (vbox2), rb_manual, TRUE, TRUE, 0);
|
|
||||||
gtk_radio_button_set_group (GTK_RADIO_BUTTON (rb_manual), rb_mode_group);
|
|
||||||
rb_mode_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (rb_manual));
|
|
||||||
GtkWidget* rb_ramp = gtk_radio_button_new_with_mnemonic (NULL, "ramp");
|
|
||||||
gtk_box_pack_start (GTK_BOX (vbox2), rb_ramp, TRUE, TRUE, 0);
|
|
||||||
gtk_radio_button_set_group (GTK_RADIO_BUTTON (rb_ramp), rb_mode_group);
|
|
||||||
rb_mode_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (rb_ramp));
|
|
||||||
GtkWidget* rb_step = gtk_radio_button_new_with_mnemonic (NULL, "step");
|
|
||||||
gtk_box_pack_start (GTK_BOX (vbox2), rb_step, TRUE, TRUE, 0);
|
|
||||||
gtk_radio_button_set_group (GTK_RADIO_BUTTON (rb_step), rb_mode_group);
|
|
||||||
rb_mode_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (rb_step));
|
|
||||||
GtkWidget* rb_prbs = gtk_radio_button_new_with_mnemonic (NULL, "prbs");
|
|
||||||
gtk_box_pack_start (GTK_BOX (vbox2), rb_prbs, TRUE, TRUE, 0);
|
|
||||||
gtk_radio_button_set_group (GTK_RADIO_BUTTON (rb_prbs), rb_mode_group);
|
|
||||||
rb_mode_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (rb_prbs));
|
|
||||||
GtkWidget* rb_sine = gtk_radio_button_new_with_mnemonic (NULL, "sine");
|
|
||||||
gtk_box_pack_start (GTK_BOX (vbox2), rb_sine, TRUE, TRUE, 0);
|
|
||||||
gtk_radio_button_set_group (GTK_RADIO_BUTTON (rb_sine), rb_mode_group);
|
|
||||||
rb_mode_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (rb_sine));
|
|
||||||
GtkWidget* rb_fixed_rpm = gtk_radio_button_new_with_mnemonic (NULL, "fixed");
|
|
||||||
gtk_box_pack_start (GTK_BOX (vbox2), rb_fixed_rpm, TRUE, TRUE, 0);
|
|
||||||
gtk_radio_button_set_group (GTK_RADIO_BUTTON (rb_fixed_rpm), rb_mode_group);
|
|
||||||
rb_mode_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (rb_fixed_rpm));
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
g_signal_connect ((gpointer) rb_idle, "toggled", G_CALLBACK (on_mode_changed), (gpointer)MB_MODES_IDLE);
|
|
||||||
g_signal_connect ((gpointer) rb_manual, "toggled", G_CALLBACK (on_mode_changed), (gpointer)MB_MODES_MANUAL);
|
|
||||||
g_signal_connect ((gpointer) rb_ramp, "toggled", G_CALLBACK (on_mode_changed), (gpointer)MB_MODES_RAMP);
|
|
||||||
g_signal_connect ((gpointer) rb_step, "toggled", G_CALLBACK (on_mode_changed), (gpointer)MB_MODES_STEP);
|
|
||||||
g_signal_connect ((gpointer) rb_prbs, "toggled", G_CALLBACK (on_mode_changed), (gpointer)MB_MODES_PRBS);
|
|
||||||
g_signal_connect ((gpointer) rb_sine, "toggled", G_CALLBACK (on_mode_changed), (gpointer)MB_MODES_SINE);
|
|
||||||
g_signal_connect ((gpointer) rb_fixed_rpm, "toggled", G_CALLBACK (on_mode_changed), (gpointer)MB_MODES_FIXED_RPM);
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Measures
|
|
||||||
//
|
|
||||||
GtkWidget *measure_frame = gtk_frame_new ("Measures");
|
|
||||||
gtk_container_set_border_width (GTK_CONTAINER (measure_frame), 10);
|
|
||||||
gtk_box_pack_start (GTK_BOX (hbox1), measure_frame, TRUE, TRUE, 0);
|
|
||||||
|
|
||||||
GtkWidget* table1 = gtk_table_new (2, 3, FALSE);
|
|
||||||
gtk_container_add (GTK_CONTAINER (measure_frame), table1);
|
|
||||||
gtk_table_set_col_spacings (GTK_TABLE (table1), 5);
|
|
||||||
|
|
||||||
GtkWidget* t_time = gtk_label_new ("time");
|
|
||||||
gtk_table_attach (GTK_TABLE (table1), t_time, 0, 1, 0, 1,
|
|
||||||
(GtkAttachOptions) (GTK_FILL),
|
|
||||||
(GtkAttachOptions) (0), 0, 0);
|
|
||||||
gtk_misc_set_alignment (GTK_MISC (t_time), 0, 0.5);
|
|
||||||
mb_gui.lab_time = gtk_label_new ("XXXX");
|
|
||||||
gtk_table_attach (GTK_TABLE (table1), mb_gui.lab_time, 1, 2, 0, 1,
|
|
||||||
(GtkAttachOptions) (GTK_FILL),
|
|
||||||
(GtkAttachOptions) (0), 0, 0);
|
|
||||||
gtk_misc_set_alignment (GTK_MISC (mb_gui.lab_time), 0, 0.5);
|
|
||||||
|
|
||||||
GtkWidget* t_throttle = gtk_label_new ("throttle");
|
|
||||||
gtk_table_attach (GTK_TABLE (table1), t_throttle, 0, 1, 1, 2,
|
|
||||||
(GtkAttachOptions) (GTK_FILL),
|
|
||||||
(GtkAttachOptions) (0), 0, 0);
|
|
||||||
gtk_misc_set_alignment (GTK_MISC (t_throttle), 0, 0.5);
|
|
||||||
mb_gui.lab_throttle = gtk_label_new ("XXXX");
|
|
||||||
gtk_table_attach (GTK_TABLE (table1), mb_gui.lab_throttle, 1, 2, 1, 2,
|
|
||||||
(GtkAttachOptions) (GTK_FILL),
|
|
||||||
(GtkAttachOptions) (0), 0, 0);
|
|
||||||
gtk_misc_set_alignment (GTK_MISC (mb_gui.lab_throttle), 0, 0.5);
|
|
||||||
|
|
||||||
GtkWidget* t_rpms = gtk_label_new ("rpms");
|
|
||||||
gtk_table_attach (GTK_TABLE (table1), t_rpms, 0, 1, 2, 3,
|
|
||||||
(GtkAttachOptions) (GTK_FILL),
|
|
||||||
(GtkAttachOptions) (0), 0, 0);
|
|
||||||
gtk_misc_set_alignment (GTK_MISC (t_rpms), 0, 0.5);
|
|
||||||
mb_gui.lab_rpms = gtk_label_new ("XXXX");
|
|
||||||
gtk_table_attach (GTK_TABLE (table1), mb_gui.lab_rpms, 1, 2, 2, 3,
|
|
||||||
(GtkAttachOptions) (GTK_FILL),
|
|
||||||
(GtkAttachOptions) (0), 0, 0);
|
|
||||||
gtk_misc_set_alignment (GTK_MISC (mb_gui.lab_rpms), 0, 0.5);
|
|
||||||
|
|
||||||
GtkWidget* t_amps = gtk_label_new ("amps");
|
|
||||||
gtk_table_attach (GTK_TABLE (table1), t_amps, 0, 1, 3, 4,
|
|
||||||
(GtkAttachOptions) (GTK_FILL),
|
|
||||||
(GtkAttachOptions) (0), 0, 0);
|
|
||||||
gtk_misc_set_alignment (GTK_MISC (t_amps), 0, 0.5);
|
|
||||||
mb_gui.lab_amps = gtk_label_new ("XXXX");
|
|
||||||
gtk_table_attach (GTK_TABLE (table1), mb_gui.lab_amps, 1, 2, 3, 4,
|
|
||||||
(GtkAttachOptions) (GTK_FILL),
|
|
||||||
(GtkAttachOptions) (0), 0, 0);
|
|
||||||
gtk_misc_set_alignment (GTK_MISC (mb_gui.lab_amps), 0, 0.5);
|
|
||||||
|
|
||||||
GtkWidget* t_thrust = gtk_label_new ("Thrust");
|
|
||||||
gtk_table_attach (GTK_TABLE (table1), t_thrust, 0, 1, 4, 5,
|
|
||||||
(GtkAttachOptions) (GTK_FILL),
|
|
||||||
(GtkAttachOptions) (0), 0, 0);
|
|
||||||
gtk_misc_set_alignment (GTK_MISC (t_thrust), 0, 0.5);
|
|
||||||
mb_gui.lab_thrust = gtk_label_new ("XXXX");
|
|
||||||
gtk_table_attach (GTK_TABLE (table1), mb_gui.lab_thrust, 1, 2, 4, 5,
|
|
||||||
(GtkAttachOptions) (GTK_FILL),
|
|
||||||
(GtkAttachOptions) (0), 0, 0);
|
|
||||||
gtk_misc_set_alignment (GTK_MISC (mb_gui.lab_thrust), 0, 0.5);
|
|
||||||
|
|
||||||
GtkWidget* t_torque = gtk_label_new ("Torque");
|
|
||||||
gtk_table_attach (GTK_TABLE (table1), t_torque, 0, 1, 5, 6,
|
|
||||||
(GtkAttachOptions) (GTK_FILL),
|
|
||||||
(GtkAttachOptions) (0), 0, 0);
|
|
||||||
gtk_misc_set_alignment (GTK_MISC (t_torque), 0, 0.5);
|
|
||||||
mb_gui.lab_torque = gtk_label_new ("XXXX");
|
|
||||||
gtk_table_attach (GTK_TABLE (table1), mb_gui.lab_torque, 1, 2, 5, 6,
|
|
||||||
(GtkAttachOptions) (GTK_FILL),
|
|
||||||
(GtkAttachOptions) (0), 0, 0);
|
|
||||||
gtk_misc_set_alignment (GTK_MISC (mb_gui.lab_torque), 0, 0.5);
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Log
|
|
||||||
//
|
|
||||||
GtkWidget *log_frame = gtk_frame_new ("Log");
|
|
||||||
gtk_container_set_border_width (GTK_CONTAINER (log_frame), 10);
|
|
||||||
gtk_box_pack_start (GTK_BOX (vbox1), log_frame, TRUE, TRUE, 0);
|
|
||||||
|
|
||||||
|
|
||||||
GtkWidget* bbox = gtk_hbutton_box_new ();
|
|
||||||
gtk_container_add (GTK_CONTAINER (log_frame), bbox);
|
|
||||||
|
|
||||||
GtkWidget* log_button = gtk_toggle_button_new_with_label( "Log" );
|
|
||||||
gtk_container_add (GTK_CONTAINER (bbox), log_button);
|
|
||||||
g_signal_connect (G_OBJECT (log_button), "toggled", G_CALLBACK (on_log_button_toggled), NULL);
|
|
||||||
|
|
||||||
mb_gui.entry_log = gtk_entry_new( );
|
|
||||||
gtk_container_add (GTK_CONTAINER (bbox), mb_gui.entry_log);
|
|
||||||
gtk_entry_set_text( GTK_ENTRY(mb_gui.entry_log), "mb_log.txt" );
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Asctech
|
|
||||||
//
|
|
||||||
|
|
||||||
GtkWidget *asctech_frame = gtk_frame_new ("Asctech");
|
|
||||||
gtk_container_set_border_width (GTK_CONTAINER (asctech_frame), 10);
|
|
||||||
gtk_box_pack_start (GTK_BOX (vbox1), asctech_frame, TRUE, TRUE, 0);
|
|
||||||
|
|
||||||
|
|
||||||
GtkWidget* as_vbox2 = gtk_vbox_new (FALSE, 0);
|
|
||||||
gtk_container_add (GTK_CONTAINER (asctech_frame), as_vbox2);
|
|
||||||
|
|
||||||
GSList *rb_addr_group = NULL;
|
|
||||||
GtkWidget* rb_front = gtk_radio_button_new_with_mnemonic (NULL, "front");
|
|
||||||
gtk_box_pack_start (GTK_BOX (as_vbox2), rb_front, TRUE, TRUE, 0);
|
|
||||||
gtk_radio_button_set_group (GTK_RADIO_BUTTON (rb_front), rb_addr_group);
|
|
||||||
rb_addr_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (rb_front));
|
|
||||||
GtkWidget* rb_back = gtk_radio_button_new_with_mnemonic (NULL, "back");
|
|
||||||
gtk_box_pack_start (GTK_BOX (as_vbox2), rb_back, TRUE, TRUE, 0);
|
|
||||||
gtk_radio_button_set_group (GTK_RADIO_BUTTON (rb_back), rb_addr_group);
|
|
||||||
rb_addr_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (rb_back));
|
|
||||||
GtkWidget* rb_left = gtk_radio_button_new_with_mnemonic (NULL, "left");
|
|
||||||
gtk_box_pack_start (GTK_BOX (as_vbox2), rb_left, TRUE, TRUE, 0);
|
|
||||||
gtk_radio_button_set_group (GTK_RADIO_BUTTON (rb_left), rb_addr_group);
|
|
||||||
rb_addr_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (rb_left));
|
|
||||||
GtkWidget* rb_right = gtk_radio_button_new_with_mnemonic (NULL, "right");
|
|
||||||
gtk_box_pack_start (GTK_BOX (as_vbox2), rb_right, TRUE, TRUE, 0);
|
|
||||||
gtk_radio_button_set_group (GTK_RADIO_BUTTON (rb_right), rb_addr_group);
|
|
||||||
rb_addr_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (rb_right));
|
|
||||||
|
|
||||||
g_signal_connect ((gpointer) rb_front, "toggled", G_CALLBACK (on_as_addr_changed), (gpointer)AS_MOT_FRONT);
|
|
||||||
g_signal_connect ((gpointer) rb_back, "toggled", G_CALLBACK (on_as_addr_changed), (gpointer)AS_MOT_BACK);
|
|
||||||
g_signal_connect ((gpointer) rb_left, "toggled", G_CALLBACK (on_as_addr_changed), (gpointer)AS_MOT_LEFT);
|
|
||||||
g_signal_connect ((gpointer) rb_right, "toggled", G_CALLBACK (on_as_addr_changed), (gpointer)AS_MOT_RIGHT);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GtkWidget* as_bbox = gtk_hbutton_box_new ();
|
|
||||||
gtk_box_pack_start (GTK_BOX (as_vbox2), as_bbox, TRUE, TRUE, 0);
|
|
||||||
//gtk_container_add (GTK_CONTAINER (asctech_frame), as_bbox);
|
|
||||||
|
|
||||||
GtkWidget* test_button = gtk_toggle_button_new_with_label( "Test" );
|
|
||||||
gtk_container_add (GTK_CONTAINER (as_bbox), test_button);
|
|
||||||
g_signal_connect (G_OBJECT (test_button), "clicked", G_CALLBACK (on_as_test_button_clicked), NULL);
|
|
||||||
|
|
||||||
GtkWidget* reverse_button = gtk_toggle_button_new_with_label( "Reverse" );
|
|
||||||
gtk_container_add (GTK_CONTAINER (as_bbox), reverse_button);
|
|
||||||
g_signal_connect (G_OBJECT (reverse_button), "clicked", G_CALLBACK (on_as_reverse_button_clicked), NULL);
|
|
||||||
|
|
||||||
|
|
||||||
return window1;
|
|
||||||
}
|
|
||||||
@@ -1,144 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
function [time, throttle, rpm, amp, thrust, torque] = read_mb_log(filename)
|
|
||||||
|
|
||||||
time=[];
|
|
||||||
throttle=[];
|
|
||||||
rpm=[];
|
|
||||||
amp=[];
|
|
||||||
thrust=[];
|
|
||||||
torque=[];
|
|
||||||
|
|
||||||
u=mopen(filename,'r');
|
|
||||||
|
|
||||||
while meof(u) == 0,
|
|
||||||
line = mgetl(u, 1);
|
|
||||||
if strindex(line, '#') ~= 1 & length(line) ~= 0,
|
|
||||||
[nb_scan, _time, _throttle, _rpm, _amp, _thrust, _torque] = msscanf(1, line, '%f %f %f %f %f %f');
|
|
||||||
if nb_scan == 6,
|
|
||||||
time = [time _time];
|
|
||||||
throttle = [throttle _throttle];
|
|
||||||
rpm = [rpm _rpm];
|
|
||||||
amp = [amp _amp];
|
|
||||||
thrust = [thrust _thrust];
|
|
||||||
torque = [torque _torque];
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
mclose(u);
|
|
||||||
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function [averaged] = average(nb_points, raw_data_throttle, raw_data_rpm)
|
|
||||||
av_rpm=zeros(1,nb_points+1);
|
|
||||||
count=zeros(1,nb_points+1);
|
|
||||||
//Summation of the Data
|
|
||||||
for i=1:length(raw_data_throttle)
|
|
||||||
idx=round(raw_data_throttle(i)*nb_points)+1;
|
|
||||||
av_rpm(idx) = av_rpm(idx) + raw_data_rpm(i);
|
|
||||||
count(idx) = count(idx) + 1;
|
|
||||||
end
|
|
||||||
|
|
||||||
// Dividing the Data by the summated points
|
|
||||||
|
|
||||||
for i=1:nb_points+1
|
|
||||||
if count(i) ~=0
|
|
||||||
av_rpm(i) = av_rpm(i) / count(i);
|
|
||||||
// printf('i=%d count=%d av_rpm=%d\n', i, count(i), av_rpm(i) );
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
averaged = av_rpm;
|
|
||||||
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
function [filtered] = low_pass_filter(f_sample, f_cut, raw_data)
|
|
||||||
|
|
||||||
delta_t = 1/f_sample;
|
|
||||||
rc = 1 / ( 2 * %pi * f_cut);
|
|
||||||
alpha = delta_t / ( delta_t + rc );
|
|
||||||
|
|
||||||
filtered=[raw_data(1)];
|
|
||||||
for i=2:length(raw_data)
|
|
||||||
fv = alpha * raw_data(i) + (1 - alpha) * filtered(i-1);
|
|
||||||
filtered = [filtered fv];
|
|
||||||
end
|
|
||||||
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Definition of the Fittin Function
|
|
||||||
// FF=Fitting Function
|
|
||||||
// x=Vector of Variables
|
|
||||||
// p=Vector of Parameters
|
|
||||||
function y=FF(x,p)
|
|
||||||
y=p(1)+((sqrt(p(2)*x) +1)-1)/p(3)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
//The criterion function
|
|
||||||
//Discrete errorfunction
|
|
||||||
//z = x Vector and y Vector of the collected Data
|
|
||||||
function e=G(p,z),
|
|
||||||
y=z(1),x=z(2);
|
|
||||||
e=y-FF(x,p),
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function [] = param_fit(av_rpm, av_throttle)
|
|
||||||
|
|
||||||
X=av_throttle;
|
|
||||||
Y=av_rpm;
|
|
||||||
Z=[X;Y];
|
|
||||||
//solve the Problem
|
|
||||||
//Initial parameters
|
|
||||||
p0 = [1;1;1];
|
|
||||||
//call the datafit function with following parameter:
|
|
||||||
//G = errorfunction
|
|
||||||
//Z = collected Data Vector
|
|
||||||
//p0= initial parameter
|
|
||||||
[p,err] = datafit(G,Z,p0);
|
|
||||||
|
|
||||||
printf('\n')
|
|
||||||
printf('p=%f\n', p)
|
|
||||||
|
|
||||||
scf(0);clf()
|
|
||||||
//plot2d(X,FF(X,pg),5) //the curve without noise
|
|
||||||
subplot(2,1,1);
|
|
||||||
plot2d(X,Y,1) // the noisy data
|
|
||||||
subplot(2,1,2);
|
|
||||||
plot2d(X,FF(X,p),12) //the solution
|
|
||||||
param_fitted=FF(X,p);
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
function r = mot_lin(t, p)
|
|
||||||
r = p(1) * t + p(2);
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function e = err_mot_lin(p, z)
|
|
||||||
r=z(1), t=z(2);
|
|
||||||
e = r - mot_lin(t, p);
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
function rpm = mot_ric_stat(throttle,param)
|
|
||||||
// maybe 1 +
|
|
||||||
tau_kq = param(1);
|
|
||||||
kv = param(2);
|
|
||||||
dv = 0.0;
|
|
||||||
rpm = (-1 + sqrt(1 + 4 * tau_kq * kv * (throttle + dv))) / (2 * tau_kq);
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function e = err_mot_ric(p, z)
|
|
||||||
r_meas = z(1);
|
|
||||||
throttle = z(2);
|
|
||||||
e = r_meas - mot_ric_stat(throttle, p);
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function rpm_dot = mot_ode(tau, kq, kv, V, rpm)
|
|
||||||
rpm_dot = -1/tau*rpm - kq * rpm^2 + kv/tau*(V);
|
|
||||||
endfunction
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
clear();
|
|
||||||
getf('mb_utils.sci');
|
|
||||||
|
|
||||||
load('averaged_ramp_geared.dat','av_throttle','av_rpm')
|
|
||||||
|
|
||||||
t_part = av_throttle(20:90);
|
|
||||||
r_part = av_rpm(20:90);
|
|
||||||
|
|
||||||
p0=[0.00001; 20000];
|
|
||||||
Z = [r_part; t_part];
|
|
||||||
//[p, err] = datafit(err_mot_lin, Z, p0);
|
|
||||||
|
|
||||||
[p, err] = datafit(err_mot_ric, Z, p0)
|
|
||||||
//p = p0;
|
|
||||||
|
|
||||||
xbasc();
|
|
||||||
//subplot(3,1,1);
|
|
||||||
xtitle('Rpms vs Throttle');
|
|
||||||
plot2d(av_throttle,av_rpm);
|
|
||||||
plot2d(t_part,r_part, 4);
|
|
||||||
|
|
||||||
|
|
||||||
r_fit = [];
|
|
||||||
for i=1:length(av_throttle)
|
|
||||||
// r_fit = [r_fit mot_lin(av_throttle(i), p)];
|
|
||||||
r_fit = [r_fit mot_ric(av_throttle(i), p)];
|
|
||||||
end
|
|
||||||
|
|
||||||
plot2d(av_throttle,r_fit, 3);
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
clear();
|
|
||||||
getf('mb_utils.sci');
|
|
||||||
|
|
||||||
//filename = "mb_log.txt";
|
|
||||||
args = sciargs();
|
|
||||||
[nb_args, foo] = size(args)
|
|
||||||
filename = args(nb_args);
|
|
||||||
filename = "asctech/log_ramp_crooked_prop.txt"
|
|
||||||
|
|
||||||
[time, throttle, rpm, amp, thrust, torque] = read_mb_log(filename);
|
|
||||||
|
|
||||||
|
|
||||||
f_sample = 250.;
|
|
||||||
fc = 100.;
|
|
||||||
f_rpm = low_pass_filter(f_sample, fc, rpm);
|
|
||||||
|
|
||||||
|
|
||||||
xbasc();
|
|
||||||
subplot(3,1,1)
|
|
||||||
xtitle('Throttle');
|
|
||||||
plot2d(time, throttle);
|
|
||||||
|
|
||||||
subplot(3,1,2)
|
|
||||||
xtitle('Rpm');
|
|
||||||
plot2d(time, rpm);
|
|
||||||
|
|
||||||
subplot(3,1,3)
|
|
||||||
xtitle('Filtered Rpm');
|
|
||||||
plot2d(time, f_rpm);
|
|
||||||
//plot2d(rpm, throttle);
|
|
||||||
|
|
||||||
save('asctech/log_ramp_crooked_prop.dat', time, throttle, rpm, amp, thrust, torque);
|
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
--------
|
|
||||||
|BUILDING|
|
|
||||||
--------
|
|
||||||
Make sure you have the environment variable RTHOME set to the absolute
|
|
||||||
path to the river_tracking directory on your system. (Place this in
|
|
||||||
your .bashrc or environment variable settings in your IDE).
|
|
||||||
|
|
||||||
Build with make.
|
|
||||||
|
|
||||||
|
|
||||||
--------------------
|
|
||||||
|USING WITH PAPARAZZI|
|
|
||||||
--------------------
|
|
||||||
In order for river_tracking to function properly with Paparazzi, you must
|
|
||||||
create the flight plan with the following specifications:
|
|
||||||
|
|
||||||
Waypoints:
|
|
||||||
----------
|
|
||||||
-Your waypoints must be set up something like this:
|
|
||||||
<waypoints>
|
|
||||||
<waypoint alt="xxx" name="HOME" x="xxx" y="xxx"/>
|
|
||||||
<waypoint name="pre_track_setup" x="xxx" y="xxx"/>
|
|
||||||
<waypoint name="pre_track_start" x="xxx" y="xxx"/>
|
|
||||||
<waypoint name="tracker" x="xxx" y="xxx"/>
|
|
||||||
...other stuff...
|
|
||||||
</waypoints>
|
|
||||||
|
|
||||||
Explanation:
|
|
||||||
-The first waypoint defined can be anything (something like HOME is good)
|
|
||||||
-The second and third waypoints defined must be set up such that a line which
|
|
||||||
passes through them will also pass through the first point on the river to be
|
|
||||||
tracked. It is recommended that they be spaced at least 100ish meters apart
|
|
||||||
to ensure that the plane will indeed be flying in a straight line once
|
|
||||||
it reaches the first point on the river
|
|
||||||
-The fourth waypoint defined is the waypoint which river_tracking will move
|
|
||||||
around. It must be placed initially on the river at the desired starting point.
|
|
||||||
-All other waypoints can be set up however you'd like.
|
|
||||||
|
|
||||||
Blocks:
|
|
||||||
-------
|
|
||||||
-Your blocks must look something like this:
|
|
||||||
<blocks>
|
|
||||||
<block name="pre_track">
|
|
||||||
<go wp="pre_track_setup"/>
|
|
||||||
<go from="pre_track_setup" wp="pre_track_start" hmode="route"/>
|
|
||||||
</block>
|
|
||||||
<block name="track">
|
|
||||||
<while cond="TRUE">
|
|
||||||
<go wp="tracker"/>
|
|
||||||
</while>
|
|
||||||
</block>
|
|
||||||
...other stuff...
|
|
||||||
</blocks>
|
|
||||||
|
|
||||||
Explanation:
|
|
||||||
-The first block defined must go through the second and third waypoints.
|
|
||||||
-The second block defined must continually go to the fourth waypoint.
|
|
||||||
-All other blocks can be set up however you'd like.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-----------
|
|
||||||
|DEVELOPMENT|
|
|
||||||
-----------
|
|
||||||
|
|
||||||
Project Layout:
|
|
||||||
---------------
|
|
||||||
All source files (.c, .h, etc) should be placed under the src directory.
|
|
||||||
The river_track executable (and other executables) will be placed in the bin
|
|
||||||
directory.
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
#Makefile written by Mitchel Humpherys
|
|
||||||
|
|
||||||
#if pkg-config --cflags opencv --libs opencv
|
|
||||||
#doesn't return something useful
|
|
||||||
#make sure PKG_CONFIG_PATH is set correctly
|
|
||||||
#Also, RTHOME must be set to the absolute path of the river_tracking
|
|
||||||
#directory in your environment.
|
|
||||||
RTSOURCE = $(RTHOME)/src
|
|
||||||
RTBIN = $(RTHOME)/bin
|
|
||||||
INCLUDES = `pkg-config --cflags --libs opencv gtk+-2.0` -I$(RTSOURCE) -lglibivy
|
|
||||||
|
|
||||||
CPP = g++ -g -Wno-deprecated
|
|
||||||
CC = gcc -g
|
|
||||||
CFLAGS = -c $(INCLUDES)
|
|
||||||
|
|
||||||
all : main
|
|
||||||
|
|
||||||
main : src/river_track.c
|
|
||||||
$(CC) src/river_track.c -o bin/river_track $(INCLUDES)
|
|
||||||
|
|
||||||
clean :
|
|
||||||
cd $(RTHOME) rm -f *.o
|
|
||||||
cd $(RTSOURCE); rm -f *.o;
|
|
||||||
cd $(RTBIN); rm -f river_track;
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <getopt.h>
|
|
||||||
#include <ivy.h>
|
|
||||||
#include <ivyloop.h>
|
|
||||||
|
|
||||||
/* callback associated to "Hello" messages */
|
|
||||||
void HelloCallback (IvyClientPtr app, void *data, int argc, char **argv)
|
|
||||||
{
|
|
||||||
const char* arg = (argc < 1) ? "" : argv[0];
|
|
||||||
IvySendMsg ("Bonjour%s", arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* callback associated to "Bye" messages */
|
|
||||||
void ByeCallback (IvyClientPtr app, void *data, int argc, char **argv)
|
|
||||||
{
|
|
||||||
IvyStop ();
|
|
||||||
}
|
|
||||||
|
|
||||||
main (int argc, char**argv)
|
|
||||||
{
|
|
||||||
/* handling of -b option */
|
|
||||||
const char* bus = 0;
|
|
||||||
char c;
|
|
||||||
while (c = getopt (argc, argv, "b:") != EOF) {
|
|
||||||
switch (c) {
|
|
||||||
case 'b':
|
|
||||||
bus = optarg;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* handling of environment variable */
|
|
||||||
if (!bus)
|
|
||||||
bus = getenv ("IVYBUS");
|
|
||||||
|
|
||||||
/* initializations */
|
|
||||||
IvyInit ("IvyTranslater", "Hello le monde", 0, 0, 0, 0);
|
|
||||||
IvyStart (bus);
|
|
||||||
|
|
||||||
/* binding of HelloCallback to messages starting with 'Hello' */
|
|
||||||
IvyBindMsg (HelloCallback, 0, "^Hello(.*)");
|
|
||||||
|
|
||||||
/* binding of ByeCallback to 'Bye' */
|
|
||||||
IvyBindMsg (ByeCallback, 0, "^Bye$");
|
|
||||||
|
|
||||||
/* main loop */
|
|
||||||
IvyMainLoop(0);
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
/*This module will do a bunch of fancy opencv stuff to figure out the
|
|
||||||
next waypoint.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "waypoint.h"
|
|
||||||
|
|
||||||
extern float ADD;
|
|
||||||
|
|
||||||
Waypoint get_next_waypoint() {
|
|
||||||
Waypoint next_wp;
|
|
||||||
|
|
||||||
/* Insert all sorts of opencv magic here */
|
|
||||||
next_wp.ac_id = 1;
|
|
||||||
next_wp.wp = 3;
|
|
||||||
next_wp.alt = 1420.;
|
|
||||||
next_wp.lat = 41.823364 + ADD;
|
|
||||||
next_wp.lon = -111.988800 + ADD;
|
|
||||||
ADD+=.00004;
|
|
||||||
return next_wp;
|
|
||||||
}
|
|
||||||
@@ -1,131 +0,0 @@
|
|||||||
/*
|
|
||||||
* File: river_track.c
|
|
||||||
* Author: mgalgs
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <Ivy/ivy.h>
|
|
||||||
#include <Ivy/ivyglibloop.h>
|
|
||||||
#include <gtk-2.0/gtk/gtk.h>
|
|
||||||
/*#include <gtk/gtk.h> is what the previous line should read when compiling
|
|
||||||
with pkg-config --cflags --libs gtk+-2.0 */
|
|
||||||
#include "nextwp.c"
|
|
||||||
#include "waypoint.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Some global variables */
|
|
||||||
float END_LAT = 0.0; //latitude of the "end" waypoint (the fifth waypoint defined in flight plan)
|
|
||||||
float END_LON = 0.0; //longitude of the "end" waypoint (the fifth waypoint defined in flight plan)
|
|
||||||
int CONTINUE = 1; //When this variable is set to 0 river_track will stop moving the waypoint around
|
|
||||||
float ADD = 0; //just to move the waypoint around for fun
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* callback associated to "Hello" messages */
|
|
||||||
void textCallback(IvyClientPtr app, void *data, int argc, char **argv)
|
|
||||||
{
|
|
||||||
const char* arg = (argc < 1) ? "" : argv[0];
|
|
||||||
IvySendMsg("Alo ai%s", arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Sets the global variables END_LAT & END_LON to the GPS coordinates
|
|
||||||
* of the end waypoint (the fifth waypoint defined in the flight plan).
|
|
||||||
*/
|
|
||||||
void set_end(IvyClientPtr app, void *data, int argc, char **argv)
|
|
||||||
{
|
|
||||||
const char *arg = (argc < 1) ? "" : argv[0];
|
|
||||||
|
|
||||||
char *current;
|
|
||||||
current = strtok(arg, " ");
|
|
||||||
current = strtok(NULL, " ");
|
|
||||||
current = strtok(NULL, " ");
|
|
||||||
current = strtok(NULL, " ");
|
|
||||||
END_LAT = atof(current);
|
|
||||||
current = strtok(NULL, " ");
|
|
||||||
END_LON = atof(current);
|
|
||||||
// fprintf(stderr, "END_LAT=%f. END_LON=%f.", END_LAT, END_LON);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Called by clicking a button */
|
|
||||||
void init_river_tracking( GtkWidget *widget, gpointer data )
|
|
||||||
{
|
|
||||||
fprintf(stderr, "initializing river tracking...\n");
|
|
||||||
/* Call function get_next_waypoint (defined in nexcwp.c)
|
|
||||||
* which returns a waypoint. */
|
|
||||||
Waypoint new_wp = get_next_waypoint();
|
|
||||||
IvySendMsg("gcs MOVE_WAYPOINT %d %d %f %f %f", \
|
|
||||||
new_wp.ac_id, 4, new_wp.lat, new_wp.lon, new_wp.alt);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Called when aircraft reaches "Block 1" (the second
|
|
||||||
* block defined in the flight plan)
|
|
||||||
*/
|
|
||||||
void start_track(IvyClientPtr app, void *data, int argc, char **argv)
|
|
||||||
{
|
|
||||||
fprintf(stderr, ".");
|
|
||||||
/* Call function get_next_waypoint (defined in nexcwp.c)
|
|
||||||
* which returns a waypoint. */
|
|
||||||
Waypoint new_wp = get_next_waypoint();
|
|
||||||
|
|
||||||
if(CONTINUE) {
|
|
||||||
IvySendMsg("gcs MOVE_WAYPOINT %d %d %f %f %f", \
|
|
||||||
new_wp.ac_id, 4, new_wp.lat, new_wp.lon, new_wp.alt); //Always move waypoint 4
|
|
||||||
}
|
|
||||||
/* else we've reached the end (we've seen the "end" waypoint in the
|
|
||||||
* picture), so don't send any message.
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Destroys the window */
|
|
||||||
static void destroy( GtkWidget *widget, gpointer data )
|
|
||||||
{
|
|
||||||
gtk_main_quit ();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int main( int argc, char *argv[] )
|
|
||||||
{
|
|
||||||
GtkWidget *window;
|
|
||||||
GtkWidget *button;
|
|
||||||
GtkWidget *box1;
|
|
||||||
|
|
||||||
char *bus=getenv("IVYBUS");
|
|
||||||
|
|
||||||
gtk_init(&argc, &argv);
|
|
||||||
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
|
||||||
gtk_container_set_border_width(GTK_CONTAINER(window), 10);
|
|
||||||
gtk_window_set_title (GTK_WINDOW (window), "River Tracking");
|
|
||||||
|
|
||||||
box1 = gtk_hbox_new (FALSE, 0);
|
|
||||||
gtk_container_add (GTK_CONTAINER (window), box1);
|
|
||||||
|
|
||||||
//first button...
|
|
||||||
button = gtk_button_new_with_label("(Re)define region of interest");
|
|
||||||
g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(init_river_tracking), 0);
|
|
||||||
gtk_box_pack_start(GTK_BOX(box1), button, TRUE, TRUE, 0);
|
|
||||||
gtk_widget_show (button);
|
|
||||||
|
|
||||||
//second button...
|
|
||||||
button = gtk_button_new_with_label("Quit");
|
|
||||||
g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(destroy), 0);
|
|
||||||
gtk_box_pack_start(GTK_BOX (box1), button, TRUE, TRUE, 0);
|
|
||||||
gtk_widget_show (button);
|
|
||||||
|
|
||||||
gtk_widget_show(box1);
|
|
||||||
gtk_widget_show(window);
|
|
||||||
|
|
||||||
IvyInit("river_track", "river_track READY", NULL, NULL, NULL, NULL);
|
|
||||||
IvyBindMsg(textCallback,0,"^river_track hello(.*)");
|
|
||||||
IvyBindMsg(start_track,0,"(NAV_STATUS 1 1 +.*)");
|
|
||||||
IvyBindMsg(set_end,0,"(WAYPOINT_MOVED 1 5 +.*)");
|
|
||||||
IvyStart(bus);
|
|
||||||
|
|
||||||
gtk_main();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
/*
|
|
||||||
* File: waypoint.h
|
|
||||||
* Author: mgalgs
|
|
||||||
*
|
|
||||||
* Created on July 28, 2008, 5:22 PM
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _WAYPOINT_H
|
|
||||||
#define _WAYPOINT_H
|
|
||||||
|
|
||||||
typedef struct Waypoint {
|
|
||||||
int ac_id;
|
|
||||||
int wp;
|
|
||||||
float lat;
|
|
||||||
float lon;
|
|
||||||
float alt;
|
|
||||||
} Waypoint;
|
|
||||||
|
|
||||||
#endif /* _WAYPOINT_H */
|
|
||||||
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
|
|
||||||
# Quiet compilation
|
|
||||||
Q=@
|
|
||||||
|
|
||||||
CC = gcc
|
|
||||||
GLIB_CFLAGS = -Wall $(shell pkg-config glib-2.0 --cflags)
|
|
||||||
GLIB_LDFLAGS = $(shell pkg-config glib-2.0 --libs) -lglibivy $(shell pcre-config --libs)
|
|
||||||
|
|
||||||
main: main.c serial_port.c
|
|
||||||
$(CC) $(GLIB_CFLAGS) -o $@ main.c serial_port.c $(GLIB_LDFLAGS)
|
|
||||||
|
|
||||||
|
|
||||||
clean:
|
|
||||||
$(Q)rm -f main
|
|
||||||
@@ -1,128 +0,0 @@
|
|||||||
#include <glib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
|
|
||||||
|
|
||||||
#include <Ivy/ivy.h>
|
|
||||||
#include <Ivy/ivyglibloop.h>
|
|
||||||
|
|
||||||
#include "serial_port.h"
|
|
||||||
|
|
||||||
#define BUF_SIZE 512
|
|
||||||
#define AC_ID 2
|
|
||||||
|
|
||||||
static struct SerialPort* sp;
|
|
||||||
static GIOChannel* ioc;
|
|
||||||
|
|
||||||
static void configure_term(struct termios *termios, speed_t *speed) {
|
|
||||||
/* input modes */
|
|
||||||
termios->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|INPCK|ISTRIP|INLCR|IGNCR
|
|
||||||
|ICRNL |IUCLC|IXON|IXANY|IXOFF|IMAXBEL);
|
|
||||||
termios->c_iflag |= IGNPAR;
|
|
||||||
/* control modes*/
|
|
||||||
termios->c_cflag &= ~(CSIZE|PARENB|CRTSCTS|PARODD|HUPCL);
|
|
||||||
termios->c_cflag |= CREAD|CS8|CSTOPB|CLOCAL;
|
|
||||||
/* local modes */
|
|
||||||
termios->c_lflag &= ~(ISIG|ICANON|IEXTEN|ECHO|FLUSHO|PENDIN);
|
|
||||||
termios->c_lflag |= NOFLSH;
|
|
||||||
/* speed */
|
|
||||||
*speed = B9600;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dump_buf ( int len, char* buf) {
|
|
||||||
|
|
||||||
static gchar buf2[BUF_SIZE];
|
|
||||||
static int cur_len = 0;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i=0; i<len; i++) {
|
|
||||||
if (buf[i] != '\r') {
|
|
||||||
if (buf[i] != 'T' && buf[i] != '.'){
|
|
||||||
buf2[cur_len] = buf[i];
|
|
||||||
cur_len++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
int force;
|
|
||||||
buf2[cur_len] = 0;
|
|
||||||
g_message("buf2: %s",buf2);
|
|
||||||
sscanf(buf2,"%d",&force);
|
|
||||||
IvySendMsg("%d X_FORCE %d", AC_ID, force);
|
|
||||||
cur_len = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//g_message("read %s and %s",buf,buf2);
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean on_serial_data_received(GIOChannel *source,
|
|
||||||
GIOCondition condition,
|
|
||||||
gpointer data) {
|
|
||||||
gchar* _buf;
|
|
||||||
GError* _err = NULL;
|
|
||||||
GIOStatus st = g_io_channel_read_line(source, &_buf, NULL, NULL, &_err);
|
|
||||||
|
|
||||||
switch (st) {
|
|
||||||
case G_IO_STATUS_AGAIN :
|
|
||||||
g_message("again");
|
|
||||||
break;
|
|
||||||
case G_IO_STATUS_NORMAL:
|
|
||||||
g_message("normal [%s]", _buf);
|
|
||||||
// faire un truc
|
|
||||||
g_free(_buf);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
g_message("something else");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
static gchar buf[BUF_SIZE];
|
|
||||||
gsize len;
|
|
||||||
|
|
||||||
g_io_channel_read_chars(source, buf, BUF_SIZE, &len, NULL);
|
|
||||||
dump_buf(len, buf);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
gboolean timeout_callback(gpointer data) {
|
|
||||||
|
|
||||||
const char* msg = "GT\n";
|
|
||||||
gsize bw;
|
|
||||||
|
|
||||||
g_io_channel_write_chars(ioc, msg, 3, &bw, NULL);
|
|
||||||
g_io_channel_flush(ioc, NULL);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
int main ( int argc, char** argv) {
|
|
||||||
|
|
||||||
sp = serial_port_new();
|
|
||||||
serial_port_open(sp, "/dev/ttyUSB1", configure_term);
|
|
||||||
|
|
||||||
ioc = g_io_channel_unix_new(sp->fd);
|
|
||||||
g_io_channel_set_encoding(ioc, NULL, NULL);
|
|
||||||
g_io_channel_set_flags (ioc,G_IO_FLAG_NONBLOCK, NULL );
|
|
||||||
g_io_add_watch (ioc, G_IO_IN, on_serial_data_received, NULL);
|
|
||||||
|
|
||||||
|
|
||||||
GMainLoop *ml = g_main_loop_new(NULL, FALSE);
|
|
||||||
|
|
||||||
IvyInit ("Wind_Tunnel", "Wind_Tunnel READY", NULL, NULL, NULL, NULL);
|
|
||||||
IvyStart("127.255.255.255");
|
|
||||||
|
|
||||||
g_timeout_add(500, timeout_callback, NULL);
|
|
||||||
|
|
||||||
g_main_loop_run(ml);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
/*
|
|
||||||
pc2rc serial port functions
|
|
||||||
Copyright (C) 2001 Antoine Drouin
|
|
||||||
|
|
||||||
This file is part of paparazzi.
|
|
||||||
|
|
||||||
paparazzi is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
paparazzi is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with paparazzi; see the file COPYING. If not, write to
|
|
||||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
|
||||||
Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include "serial_port.h"
|
|
||||||
|
|
||||||
#define TRACE(type,fmt,args...)
|
|
||||||
#define TRACE_ERROR 1
|
|
||||||
|
|
||||||
struct SerialPort* serial_port_new() {
|
|
||||||
struct SerialPort* this = malloc(sizeof(struct SerialPort));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* opens serial port and setup the terminal
|
|
||||||
*/
|
|
||||||
guint
|
|
||||||
serial_port_open(struct SerialPort* this, const char* device,
|
|
||||||
void(*term_conf_callback)(struct termios*, speed_t*)) {
|
|
||||||
speed_t speed;
|
|
||||||
if ((this->fd = open(device, O_RDWR)) < 0) {
|
|
||||||
TRACE(TRACE_ERROR,"opening %s (%s)\n", device, strerror(errno));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (tcgetattr(this->fd, &this->orig_termios) < 0) {
|
|
||||||
TRACE(TRACE_ERROR,"getting term settings (%s)\n", strerror(errno));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
this->cur_termios = this->orig_termios;
|
|
||||||
term_conf_callback(&this->cur_termios, &speed);
|
|
||||||
if (cfsetispeed(&this->cur_termios, speed)) {
|
|
||||||
TRACE(TRACE_ERROR,"setting term speed (%s)\n", strerror(errno));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (tcsetattr(this->fd, TCSADRAIN, &this->cur_termios)) {
|
|
||||||
TRACE(TRACE_ERROR,"setting term attributes (%s)\n", strerror(errno));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* closes serial port and restore term settings
|
|
||||||
*/
|
|
||||||
guint
|
|
||||||
serial_port_close(struct SerialPort* this) {
|
|
||||||
if (tcflush(this->fd, TCIOFLUSH)) {
|
|
||||||
TRACE(TRACE_ERROR,"flushing (%s)\n", strerror(errno));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (tcsetattr(this->fd, TCSADRAIN, &this->orig_termios)) { // Restore modes.
|
|
||||||
TRACE(TRACE_ERROR,"restoring term attributes (%s)\n", strerror(errno));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (close(this->fd)) {
|
|
||||||
TRACE(TRACE_ERROR,"closing (%s)\n", strerror(errno));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
#ifndef SERIAL_PORT_H
|
|
||||||
#define SERIAL_PORT_H
|
|
||||||
|
|
||||||
#include <termios.h>
|
|
||||||
#include <glib.h>
|
|
||||||
|
|
||||||
struct SerialPort {
|
|
||||||
int fd; /* serial device fd */
|
|
||||||
struct termios orig_termios; /* saved tty state structure */
|
|
||||||
struct termios cur_termios; /* tty state structure */
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct SerialPort* serial_port_new();
|
|
||||||
guint serial_port_open(struct SerialPort* this, const char* device,
|
|
||||||
void(*term_conf_callback)(struct termios*, speed_t*));
|
|
||||||
guint serial_port_close(struct SerialPort* this);
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
Reference in New Issue
Block a user