global SIMULATION; SIMULATION = 0; % Paramètres de lecture DIRNAME = "/home/geoffrey/CdF/cdf2018-principal/log/"; FILENAME = "000655.csv"; PATH = DIRNAME + FILENAME; % Paramètres de simulation global SIMULATION_TIME SIMULATION_DT; SIMULATION_TIME = 10; SIMULATION_DT = 1e-15; %BEGIN DIMENSIONS % Dimensions pistes global pisteWidth pisteHeight pisteOrigX pisteOrigY; pisteWidth = 3000.0; pisteHeight = 2000.0; pisteOrigX = 0.0; pisteOrigY = 0.0; % Dimensions robot global width height distanceBetweenWheels wheelDiameter wheelPerimeter motorSpeedGainRPMpV motorSpeedGain motorNominalTension motorControllerAlimentation motorControllerReference motorSaturationMin motorSaturationMax pwmMax coderResolution coderDataFactor coderDataResolution cranReducOut cranReducIn reducRatio coderFullResolution avPerCycle; width = 250.0; % mm (from meca) height = 100.0; % mm (from random) distanceBetweenWheels = width; % mm (from meca) wheelDiameter = 80.0; % mm (from meca) wheelPerimeter = (wheelDiameter * pi); % mm motorSpeedGainRPMpV = 233.0; % rpm/V (from datasheet) motorSpeedGain = (motorSpeedGainRPMpV / 60.0); % motor rev/s/V motorNominalTension = 24.0; % V (from datasheet) motorControllerAlimentation = 24.0; % V (from elec) motorControllerReference = 5; % V (from wiring) motorSaturationMin = 0; % V (from random) motorSaturationMax = 3.0; % V (from testing) pwmMax = 3.3; % V (from FPGA datasheet) coderResolution = 370.0; % cycles/motor rev coderDataFactor = 4.0; % increments/motor cycles coderDataResolution = (coderResolution * coderDataFactor); % cycles/motor rev cranReducOut = 48.0; % nb crans (from meca) cranReducIn = 12.0; % nb crans (from meca) reducRatio = (cranReducIn / cranReducOut); % reduction ratio coderFullResolution = (coderDataResolution / reducRatio); % cycles / wheel rev avPerCycle = (wheelPerimeter / coderFullResolution); % mm % Constantes asservissement global dDirEcartMin dDirEcartMax oDirEcartMin oDirEcartMax oGain oEcartMax; dDirEcartMin = 7.0; % mm dDirEcartMax = 10.0; % mm oDirEcartMin = (5.0 / 360.0 * 2.0 * pi); % rad oDirEcartMax = (25.0 / 360.0 * 2.0 * pi); % rad oEcartMax = (25.0 / 360.0 * 2.0 * pi); % rad oGain = 5.0; P = 5.0; I = 0.0; D = 0.0; %END DIMENSIONS global s; if SIMULATION == 1 % Génération de la consigne xinit = 50; yinit = 50; oinit = 4 * pi; d1t = 2; d1x = -300; d1y = 0; d1o = 2 * pi; dt = SIMULATION_DT; global xcons ycons ocons; xcons = timeseries([xinit, xinit, d1x, d1x], [0 d1t-dt d1t SIMULATION_TIME]); ycons = timeseries([yinit, yinit, d1y, d1y], [0 d1t-dt d1t SIMULATION_TIME]); ocons = timeseries([oinit, oinit, d1o, d1o], [0 d1t-dt d1t SIMULATION_TIME]); % Simulation disp("Lancement de la simulation"); s = sim("modelisation", "StopTime", string(SIMULATION_TIME), "MinStep", string(SIMULATION_DT)); fprintf("Simulation sampling rate: %f Hz\n", length(s.tout)/SIMULATION_TIME); else disp("Ouverture des données"); T = readtable(PATH); % Données pratiques → données théoriques T.time(1) = 0; T.x = T.xConnu; T.y = T.yConnu; T.o = T.oConnu; disp("Enregistrement des données"); s = containers.Map; for name=T.Properties.VariableNames nameChar = char(name); s(nameChar) = timeseries(T.(nameChar), T.time); end % Modification pour faire passer comme une simu td = getTimePoints(); SIMULATION_TIME = td(end); end % Graphes clf global p; % Évolution spatiale subplot(2, 2, 1); initGraph updateToTime(SIMULATION_DT); % Roues p = subplot(2, 2, 2); hold on; timeGraph(["lVolt", "rVolt", "lErr", "rErr"]); addLimitline(p, -motorSaturationMin); addLimitline(p, -motorSaturationMax); addLimitline(p, motorSaturationMin); addLimitline(p, motorSaturationMax); addLimitline(p, 0); title("Roues"); xlabel("Temps (s)"); ylabel("Tension (V)"); legend("Gauche", "Droite", "Err. gauche", "Err. droite"); % Distance p = subplot(2, 2, 3); hold on; %timeGraph(["dDirEcart", "dErr"]); timeGraph(["dDirEcart", "dErr", "secFront", "secBack"]); addLimitline(p, dDirEcartMin); addLimitline(p, dDirEcartMax); title("Distance"); xlabel("Temps (s)"); ylabel("Distance (mm)"); %legend("Ecart direction", "Err. retenue"); legend("Ecart direction", "Err. retenue", "Distance avant", "Distance arrière"); % Rotation p = subplot(2, 2, 4); hold on; timeGraph(["oDirEcart", "oEcart", "oErr"]); addLimitline(p, oDirEcartMax); addLimitline(p, oDirEcartMin); addLimitline(p, -oDirEcartMax); addLimitline(p, -oDirEcartMin); title("Rotation"); xlabel("Temps (s)"); ylabel("Angle (rad)"); legend("Ecart direction", "Ecart orientation", "Err. retenue"); % Fonctions function ts = getTS(name) global SIMULATION s; if SIMULATION == 1 ts = s.(name); else name = char(name); if s.isKey(name) ts = s(name); else fprintf("Données inconnues : %s\n", name); ts = timeseries(); end end end function pt = getTimePoints() global SIMULATION s; if SIMULATION == 1 pt = s.tout; else ts = getTS('time'); pt = ts.Time; end end function timeGraph(series) global SIMULATION_TIME p; m = inf; M = -inf; for sname=series serie = getTS(sname); plot(serie); if ~isempty(serie.Data) m = min(m, min(serie)); end if ~isempty(serie.Data) M = max(M, max(serie)); end end xlim([0 SIMULATION_TIME]); if (abs(m) ~= inf) && (abs(M) ~= inf) ylim([m M+1E-9]); end addTimeline(p); end function addLimitline(p, x) line(p.XLim, [x x], 'Color', [0.8 0.8 0.8]); end function addTimeline(p) global t timelines; timeline = line([t t], p.YLim, 'Color', [0 0 0]); timelines = [timelines timeline]; end function play() global SIMULATION_TIME speed t playing; if playing == 1 return end startCpu=cputime; startT=t; n=0; playing=1; while t