Advertisement
Guest User

Untitled

a guest
Mar 9th, 2013
144
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.  
  2. import net.sf.openrocket.aerodynamics.FlightConditions;
  3. import net.sf.openrocket.rocketcomponent.FinSet;
  4. import net.sf.openrocket.rocketcomponent.RocketComponent;
  5. import net.sf.openrocket.simulation.FlightDataType;
  6. import net.sf.openrocket.simulation.SimulationStatus;
  7. import net.sf.openrocket.simulation.exception.SimulationException;
  8. import net.sf.openrocket.simulation.listeners.AbstractSimulationListener;
  9. import net.sf.openrocket.unit.UnitGroup;
  10. import net.sf.openrocket.util.MathUtil;
  11.  
  12. /**
  13.  * An example listener that applies a PI-controller to adjust the cant of fins
  14.  * named "CONTROLPY" to control the rocket's pitch (for now) and yaw (l8r).
  15.  *
  16.  * @author Sampo Niskanen <sampo.niskanen@iki.fi>
  17.  * modified by me
  18.  */
  19. public class PitchYawControlListener extends AbstractSimulationListener {
  20.    
  21.     // Name of control fin set
  22.     private static final String CONTROL_FIN_NAME1 = "CONTROLPYLEFT";
  23.     private static final String CONTROL_FIN_NAME2 = "CONTROLPYRIGHT";  
  24.    
  25.     // Define custom flight data type
  26.     private static final FlightDataType FIN_CANT_TYPE = FlightDataType.getType("Control fin cant", UnitGroup.UNITS_ANGLE);
  27.    
  28.     // Simulation time at which PID controller is activated
  29.     private static final double START_TIME = 0.5;
  30.    
  31.     // Desired pitch rate (rad/sec)
  32.     private static final double SETPOINT = 0.0;
  33.    
  34.     // Maximum control fin turn rate (rad/sec)
  35.     private static final double TURNRATE = 10 * Math.PI / 180;
  36.    
  37.     // Maximum control fin angle (rad)
  38.     private static final double MAX_ANGLE = 15 * Math.PI / 180;
  39.    
  40.  
  41.     /*
  42.      * PID parameters
  43.      *
  44.      * At M=0.3 KP oscillation threshold between 0.35 and 0.4.    Good KI=3
  45.      * At M=0.6 KP oscillation threshold between 0.07 and 0.08    Good KI=2
  46.      * At M=0.9 KP oscillation threshold between 0.013 and 0.014  Good KI=0.5
  47.      */
  48.     private static final double KP = 0.007;
  49.     private static final double KI = 0.2;
  50.    
  51.  
  52.  
  53.  
  54.     private double pitchrate;
  55.     private double prevTime = 0;
  56.     private double intState = 0;
  57.     private double finPosition = 0;
  58.    
  59.    
  60.  
  61.     @Override
  62.     public FlightConditions postFlightConditions(SimulationStatus status, FlightConditions flightConditions) {
  63.         // Store the current pitch rate for later use
  64.         pitchrate = flightConditions.getPitchRate();
  65.         return null;
  66.     }
  67.    
  68.    
  69.     @Override
  70.     public void postStep(SimulationStatus status) throws SimulationException {
  71.        
  72.         // Activate PID controller only after a specific time
  73.         if (status.getSimulationTime() < START_TIME) {
  74.             prevTime = status.getSimulationTime();
  75.             return;
  76.         }
  77.        
  78.         // Find the fin set named CONTROLPYLEFT
  79.         FinSet finset1 = null;
  80.         for (RocketComponent c : status.getConfiguration()) {
  81.             if ((c instanceof FinSet) && (c.getName().equals(CONTROL_FIN_NAME1))) {
  82.                 finset1 = (FinSet) c;
  83.                 break;
  84.             }
  85.         }
  86.         if (finset1 == null) {
  87.             throw new SimulationException("A fin set with name '" + CONTROL_FIN_NAME1 + "' was not found");
  88.         }
  89.        
  90.         // Find the fin set named CONTROLPYRIGHT
  91.         FinSet finset2 = null;
  92.         for (RocketComponent c : status.getConfiguration()) {
  93.             if ((c instanceof FinSet) && (c.getName().equals(CONTROL_FIN_NAME2))) {
  94.                 finset2 = (FinSet) c;
  95.                 break;
  96.             }
  97.         }
  98.         if (finset2 == null) {
  99.             throw new SimulationException("A fin set with name '" + CONTROL_FIN_NAME2 + "' was not found");
  100.         }
  101.        
  102.  
  103.         // Determine time step
  104.         double deltaT = status.getSimulationTime() - prevTime;
  105.         prevTime = status.getSimulationTime();
  106.        
  107.  
  108.         // PID controller
  109.         double error = SETPOINT - pitchrate;
  110.        
  111.         double p = KP * error;
  112.         intState += error * deltaT;
  113.         double i = KI * intState;
  114.        
  115.         double value = p + i;
  116.        
  117.  
  118.         // Clamp the fin angle between -MAX_ANGLE and MAX_ANGLE
  119.         if (Math.abs(value) > MAX_ANGLE) {
  120.             System.err.printf("Attempting to set angle %.1f at t=%.3f, clamping.\n",
  121.                     value * 180 / Math.PI, status.getSimulationTime());
  122.             value = MathUtil.clamp(value, -MAX_ANGLE, MAX_ANGLE);
  123.         }
  124.        
  125.  
  126.         // Limit the fin turn rate
  127.         if (finPosition < value) {
  128.             finPosition = Math.min(finPosition + TURNRATE * deltaT, value);
  129.         } else {
  130.             finPosition = Math.max(finPosition - TURNRATE * deltaT, value);
  131.         }
  132.        
  133.         // Set the control fin cant and store the data
  134.         finset1.setCantAngle(finPosition);
  135.         finset2.setCantAngle(finPosition*-1);
  136.         status.getFlightData().setValue(FIN_CANT_TYPE, finPosition);
  137.        
  138.     }
  139. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement