/* This file is part of JOP, the Java Optimized Processor see <http://www.jopdesign.com/> Copyright (C) 2010, Wolfgang Puffitsch <wpuffits@mail.tuwien.ac.at> 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 3 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, see <http://www.gnu.org/licenses/>. */ package cruiser.control; import joprt.RtThread; import cruiser.common.*; public class Controller implements Runnable { private final SpeedManager manager; public Controller(SpeedManager manager) { this.manager = manager; } private int integralError = 0; private int lastDelta = 0; private int pidControl(int target, int current) { int delta = target - current; int P = delta; int I = (integralError*255)/256 + delta; integralError = I; int D = delta - lastDelta; lastDelta = delta; // System.err.println("P:\t"+P+"\tI:\t"+I+"\tD:\t"+D); return 64*P+I/8+D/256; } private void control() { // estimated current speed int currentSpeed = manager.getCurrentSpeed(); int targetSpeed = manager.getTargetSpeed(); // System.err.println("Estimated speed: "+currentSpeed); // System.err.println("Target speed: "+targetSpeed); // a standard PID controller int controlValue = pidControl(targetSpeed, currentSpeed); // System.err.println("Ctrl: "+controlValue); // "nearly zero" is not quite zero... if (targetSpeed == 0 && currentSpeed < 33 && currentSpeed > -33) { controlValue = -0x7fff; } // cap controlValue to valid range if (controlValue > 0x7fff) { controlValue = 0x7fff; } else if (controlValue < -0x7fff) { controlValue = -0x7fff; } // send control messages WireMessage msg; if (controlValue > 0) { msg = new WireControlMessage(WireMessage.Type.BRAKE, (short)0); System.out.print(msg.toString()); msg = new WireControlMessage(WireMessage.Type.THROTTLE, (short)controlValue); System.out.print(msg.toString()); } else if (controlValue < 0) { msg = new WireControlMessage(WireMessage.Type.BRAKE, (short)-controlValue); System.out.print(msg.toString()); msg = new WireControlMessage(WireMessage.Type.THROTTLE, (short)0); System.out.print(msg.toString()); } } public void run() { for (;;) { control(); RtThread.currentRtThread().waitForNextPeriod(); } } }