Advertisement
Guest User

pitch yaw control

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