package { import flash.display.*; import flash.events.*; import fl.controls.*; public class Main extends MovieClip { //Nos trois coefficients PID en % private var kP:Number = 20; private var kI:Number = 10; private var kD:Number = 0; private var lastError:Number = 0; private var errSum:Number = 0; private var consigne:Number = 0; // private function computePID(error:Number):Number { var P:Number, I:Number, D:Number; errSum += error; //Somme les erreurs depuis le début var errDif:Number = error - lastError; //Calcule la variation de l'erreur lastError = error; P = error * kP; //Proportionnelle I = errSum * kI; //Intégrale D = errDif * kD; //Dérivée return (P + I + D)/100; //Le résultat est la somme des trois en % } private function resetPID():void { errSum = 0; lastError = 0; } //function que si repete 30 fois par sg private function tick(e:Event) { if (physiqueInitiated) { vel += grav ; vel *= (1 - friction); } if (controleurInitiated) { var error:Number = consigne - (pos+vel) ; var result:Number = computePID(error); if (result < 0) result = Math.max( - maxVel, result); else if (!doubleDirection) result = vel; else result = Math.min(maxVel, result); vel = result; } pos += vel ; // ont touche le sol if ( pos > maxY ) { vel = -vel; pos = maxY; } graf.save(pos); //rendu dessein.y = pos; } //physique simulé private var pos:Number = 0; private var vel:Number = 0; private var grav:Number = 2; private var friction:Number = 0.05; // sol private var maxY:int ; // moteur max private var maxVel:Number = 100; // system private var dessein:MovieClip; private var graf:GraphiqueTemps; private var spacer:uint = 50; private var bt:Sprite; private var controleurInitiated:Boolean = false; private var physiqueInitiated:Boolean = true; private var doubleDirection:Boolean = true; // INIT public function Main() { addEventListener(Event.ADDED_TO_STAGE, init); } private function init(e:Event):void { stage.align = StageAlign.TOP_LEFT; stage.scaleMode = StageScaleMode.NO_SCALE; stage.stageFocusRect = false; initUI(); initAnim(); dessein = new Ascenseur(); dessein.mouseEnabled = false; dessein.x = spacer; pos = dessein.y = 0; graf = new GraphiqueTemps(1); graf.mouseEnabled = false; graf.x = spacer * 2 + dessein.width; resize(); // ont le montre a l'ecran addChild(graf); addChild(dessein); removeEventListener(Event.ADDED_TO_STAGE, init); stage.addEventListener(Event.RESIZE, resize); } private function initAnim():void { bt = new Sprite(); bt.graphics.beginFill(0xE9E9E9); bt.graphics.drawRect(0, 0, 1,1); addChild(bt); bt.addEventListener(MouseEvent.MOUSE_DOWN, press); stage.addEventListener(Event.ENTER_FRAME, tick); } private function initUI():void{ UI.btOK.addEventListener(MouseEvent.CLICK, btOkCLick); var result:Number = maxVel * 30 ; UI.inputTextVelMotor.text = result.toString(); UI.inputTextP.text = kP.toString(); UI.inputTextI.text = kI.toString(); UI.inputTextD.text = kD.toString(); result = friction * 100; UI.inputTextGrav.text = grav.toString(); UI.inputTextFric.text = result.toString(); UI.checkcontroleurInitiated.selected = controleurInitiated; UI.checkPhysiqueInitiated.selected = physiqueInitiated; UI.checkDoubleDirection.selected = doubleDirection; } //UI private function resize(e:Event=null):void { trace("resize"); graf.setSize(stage.stageWidth - spacer * 2 - dessein.width -UI.width , stage.stageHeight); UI.x = stage.stageWidth - UI.width; bt.width = UI.x ; bt.height = stage.stageHeight; maxY = stage.stageHeight - 100; } private function btOkCLick(e:MouseEvent):void { maxVel = parseFloat(UI.inputTextVelMotor.text)/30; kP = parseFloat(UI.inputTextP.text); kI = parseFloat(UI.inputTextI.text); kD = parseFloat(UI.inputTextD.text); grav = parseFloat(UI.inputTextGrav.text); friction = parseFloat(UI.inputTextFric.text)/100; if (controleurInitiated != UI.checkcontroleurInitiated.selected)resetPID(); if (physiqueInitiated != UI.checkPhysiqueInitiated.selected) vel = 0; controleurInitiated = UI.checkcontroleurInitiated.selected; physiqueInitiated = UI.checkPhysiqueInitiated.selected; doubleDirection = UI.checkDoubleDirection.selected; } private function press(e:MouseEvent):void { controleurInitiated = UI.checkcontroleurInitiated.selected = true; resetPID(); vel = 0; consigne = mouseY; } } } import flash.display.*; import flash.events.*; class GraphiqueTemps extends Sprite { private var listValue:Array; private var _w:uint; private var _h:uint; private var _step:uint; private var limit:uint; private var _count:uint; function GraphiqueTemps (step:uint) { _step = step; reset(); } public function setSize(w:uint,h:uint) { _w = w; _h = h; limit = w / _step; var len:uint = listValue.length; listValue.splice(0, len - limit); } public function save(value:Number):void { if (_count++ >= _step) { if(listValue.length > limit) listValue.shift(); listValue.push(value); _count = 0; draw(); } } private function draw():void { graphics.clear(); graphics.lineStyle(1); graphics.drawRect(0,0,_w,_h); graphics.lineStyle(1); graphics.moveTo(0, listValue[0]); for (var i:int = 1; i < listValue.length ; i++){ graphics.lineTo(i*_step,listValue[i]); } } public function reset():void { listValue = new Array(); } }