View Javadoc

1   package cz.cuni.amis.pogamut.usar2004.samples;
2   
3   import cz.cuni.amis.pogamut.base.utils.guice.AgentScoped;
4   import cz.cuni.amis.pogamut.base3d.worldview.object.*;
5   import cz.cuni.amis.pogamut.usar2004.agent.*;
6   import cz.cuni.amis.pogamut.usar2004.agent.module.configuration.*;
7   import cz.cuni.amis.pogamut.usar2004.agent.module.datatypes.*;
8   import cz.cuni.amis.pogamut.usar2004.agent.module.logic.USAR2004BotLogicController;
9   import cz.cuni.amis.pogamut.usar2004.agent.module.nfo.NfoStartPoses;
10  import cz.cuni.amis.pogamut.usar2004.agent.module.sensor.SensorLaser;
11  import cz.cuni.amis.pogamut.usar2004.agent.module.master.SensorMasterModule;
12  import cz.cuni.amis.pogamut.usar2004.agent.module.master.ConfigMasterModule;
13  import cz.cuni.amis.pogamut.usar2004.agent.module.master.GeometryMasterModule;
14  import cz.cuni.amis.pogamut.usar2004.agent.module.master.ResponseModule;
15  import cz.cuni.amis.pogamut.usar2004.agent.module.master.SensorSpecificModule;
16  import cz.cuni.amis.pogamut.usar2004.agent.module.master.StateMasterModule;
17  import cz.cuni.amis.pogamut.usar2004.agent.module.state.SuperState;
18  import cz.cuni.amis.pogamut.usar2004.communication.messages.usarcommands.*;
19  import cz.cuni.amis.pogamut.usar2004.communication.messages.usarinfomessages.NfoMessage;
20  import cz.cuni.amis.pogamut.usar2004.utils.*;
21  import cz.cuni.amis.utils.exception.PogamutException;
22  import java.util.logging.Level;
23  
24  /**
25   * This robot is designed for the map ONS-PointLookOut-250
26   *
27   * @author vejmanm
28   */
29  @AgentScoped
30  public class Submarine extends USAR2004BotLogicController<USAR2004Bot>
31  {
32      /**
33       * Method triggered after Game is initialized and STARTPOSES obtained. Tt will spawn the robot into the environment.
34       * @param nfom NfoMessge containing STARTPOSES
35       */
36      @Override
37      public void robotInitialized(NfoMessage nfom)
38      {
39          super.robotInitialized(nfom);
40          logicInitialize(logicModule);
41          //getAct().act(new GetStartPoses());
42          getAct().act(new Initialize("USARBot.Submarine", "P2DX sample robot", new Location(229.31, -651.48, 12.42), null));
43          System.out.println(logicModule.isRunning());
44  
45      }
46  
47      @Override
48      public void initializeController(USAR2004Bot bot)
49      {
50          super.initializeController(bot);
51          //startPoses = new NfoStartPoses(bot);
52          //begin = new NfoBeginMapInfo(bot);
53      }
54      private final double descendingLatch = 0.05f;//how fast should it drop the level while descending
55      private final double descendingRate = 0.5f;//how much severly should it correct the level by steering the sternPlane
56      private final double steerRate = 0.4f;//how much should it steer
57      private final int submarineLevel = 4;//how far from the bottom of the sea should it try to keep the sub.
58      //properties needed for logic run:
59      private boolean parametersObtained = false;
60      private double maxRudderAngle = 0;
61      private double maxSternPlaneAngle = 0;
62      private double maxPropellerSpeed = 0;
63      private double cameraMaxFov = 0;
64      private double cameraMinFov = 0;
65      private double cameraActFov = 0;
66      private double cameraInc = 0.01f;
67      private String cameraName = "";
68      private String cameraType = "";
69      private double laserRange = 0;
70      private double laserTime = 0;
71      private double previousLaserRange = 0;
72      private double previousLaserTime = 0;
73      private double cameraRotationSpeed = 0;
74      private double cameraTilt = 0;
75      private double cameraTiltInc = cameraInc;
76      private double cameraMaxTilt = 0;
77      private double cameraMinTilt = 0;
78      private String mispkgName = "";
79      private double time = 0;
80      //works till the battery is dead
81  
82      /**
83       * this method is triggered by receipt of STA message. This is where all behaviour is controlled
84       * @throws PogamutException 
85       */
86      @Override
87      public void logic() throws PogamutException
88      {
89          super.logic();
90  
91          obtainLaserRange();
92  
93          double steer = 0;
94          if(time % 200 < 100)
95          {
96              steer = steerRate;
97          }
98          else
99          {
100             steer = -steerRate;
101         }
102 
103         if(laserRange > submarineLevel)
104         {
105             double desc = 0;
106             if(previousLaserRange - laserRange < descendingLatch)
107             {//either descend/rise or steer! - either correct the level or steer
108                 desc = descendingRate;
109                 steer = 0;
110             }
111             bot.getAct().act(new DriveNautic(maxPropellerSpeed, maxRudderAngle * steer, maxSternPlaneAngle * desc, false, false));
112         }
113         else
114         {
115             //if sub is dropping it should go up, else she should steer a littlebit
116             double desc = 0;
117             if(previousLaserRange - laserRange > 0)
118             {
119                 desc = descendingRate;
120                 steer = 0;
121             }
122             if(laserRange < 0.5)
123             {
124                 bot.getAct().act(new DriveNautic(-maxPropellerSpeed, maxRudderAngle * -Math.signum(steer), -maxSternPlaneAngle, false, false));
125             }
126             else
127             {
128                 bot.getAct().act(new DriveNautic(maxPropellerSpeed, maxRudderAngle * steer, -maxSternPlaneAngle * desc, false, false));
129             }
130         }
131         System.out.println(laserRange);
132         System.out.println(previousLaserRange);
133         System.out.println(time);
134 
135         this.time = staModule.getStatesByClass(SuperState.class).get(0).getTime();
136 
137         if(!parametersObtained)
138         {
139             getConfig();
140         }
141         else
142         {
143             zoomCamera();
144             rotateCamera();
145         }
146     }
147 
148     /**
149      * Sets constant speed of camera roatation and repeatedly tilts the camera
150      * from min angle to max.
151      */
152     private void rotateCamera()
153     {
154         if(cameraTilt >= cameraMaxTilt || cameraTilt <= cameraMinTilt)
155         {
156             cameraTiltInc *= -1;
157         }
158         cameraTilt += cameraTiltInc;
159         //{Order int} ‘int’ is optional (0 by default) and indicates the control mode. ‘0’ means angle control, ‘1’ means speed control, and ‘2’ means torque control. 
160         int[] links = new int[]
161         {
162             1, 2
163         };
164         double[] values = new double[]
165         {
166             cameraRotationSpeed, cameraTilt
167         };
168         int[] orders = new int[]
169         {
170             1, 0
171         };
172         bot.getAct().act(new MissionPackage(mispkgName, links, values, orders));
173     }
174 
175     /**
176      * Repeatedly sets the FOV of the camera from one extreme to another.
177      */
178     private void zoomCamera()
179     {
180         if(cameraActFov >= cameraMaxFov || cameraActFov <= cameraMinFov)
181         {
182             cameraInc *= -1;
183         }
184         cameraActFov += cameraInc;
185         bot.getAct().act(new SetCamera(cameraType, cameraName, cameraActFov));
186     }
187 
188     /**
189      * Checks for new messages from sensor module and updates current and previous readings.
190      */
191     private void obtainLaserRange()
192     {
193         if(senModule.isReady())
194         {
195             if(senModule.getSensorsBySensorType(SensorType.LASER_SENSOR).size() > 0)
196             {
197                 SensorLaser range = (SensorLaser) senModule.getSensorsBySensorType(SensorType.LASER_SENSOR).get(0);
198                 //sampling is slower than calling this method, so range has potentially old news. to prevent spoiling the lastRange we make sure, that we read the laserRange just as fresh
199                 previousLaserTime = laserTime;
200                 laserTime = range.getTime();
201                 if(previousLaserTime != laserTime)
202                 {
203                     previousLaserRange = laserRange;
204                 }
205                 laserRange = range.getRangeAt(0);
206             }
207         }
208     }
209 
210     /**
211      * Obtaining of configuration information in several steps. It is unable to obtain all data in one logic cycle.
212      */
213     private void getConfig()
214     {
215         if(!confModule.isReady())
216         {
217             //get properties from server about the robot and the camera
218             confModule.queryConfigurationByType("Robot");
219         }
220         else if(confModule.getNonEmptyDescription().size() < 2)
221         {
222             //if I write those two queries just one after another it will not be quick enough to record the second query. So i could go ahead and write sth. like Thread.Sleep(10); or something...
223             confModule.queryConfigurationByType("Camera");
224         }
225         else if(confModule.getNonEmptyDescription().size() < 3)
226         {
227             confModule.queryConfigurationByType("MisPkg");
228         }
229         else//once we've got them lets save values and say that we are good to go.
230         {
231             ConfigNautic robotCfg = (ConfigNautic) confModule.getConfigurationsByConfigType(ConfigType.NAUTIC_VEHICLE).get(0);
232             for(String feature : robotCfg.getFeatureNames())
233             {
234                 System.out.println(feature + ": " + robotCfg.getFeatureValueBy(feature));
235             }
236             ConfigSensor cameraCfg = (ConfigSensor) confModule.getConfigurationsByType("Camera").get(0);
237             for(String feature : cameraCfg.getFeatureNames())
238             {
239                 System.out.println(feature + ": " + cameraCfg.getFeatureValueBy(feature));
240             }
241             ConfigMissionPackage mispkgConfig = (ConfigMissionPackage) confModule.getConfigurationsByConfigType(ConfigType.MISSION_PACKAGE).get(0);
242 
243 
244             //getParameters
245             maxRudderAngle = Float.parseFloat(robotCfg.getFeatureValueBy("MaxRudderAngle"));
246             maxSternPlaneAngle = Float.parseFloat(robotCfg.getFeatureValueBy("MaxSternPlaneAngle"));
247             maxPropellerSpeed = Float.parseFloat(robotCfg.getFeatureValueBy("MaxPropellerSpinSpeed"));
248 
249             cameraMaxFov = Float.parseFloat(cameraCfg.getFeatureValueBy("CameraMaxFov"));
250             cameraMinFov = Float.parseFloat(cameraCfg.getFeatureValueBy("CameraMinFov"));
251             cameraActFov = Float.parseFloat(cameraCfg.getFeatureValueBy("CameraDefFov"));
252 
253             cameraName = cameraCfg.getName();
254             cameraType = cameraCfg.getType();
255 
256 
257             mispkgName = mispkgConfig.getName(); //name of the missionpackage which the camera is based on.
258             cameraRotationSpeed = mispkgConfig.getMaxSpeedAt(0); //max pan speed
259             cameraMaxTilt = mispkgConfig.getMaxRangeAt(1);//max tilt
260             cameraMinTilt = mispkgConfig.getMinRangeAt(1);//min tilt
261 
262             //setFlag
263             parametersObtained = true;
264             //data from the first run - got from SystemConsole thanks to those for cycles above these properties:
265             //MaxRudderAngle: 0.4363
266             //MaxSternPlaneAngle: 0.4363
267             //MaxPropellerSpinSpeed: 6.2831
268             //PropellerPitch: 0.3048
269             //CameraMaxFov: 2.0943
270             //CameraMinFov: 0.3491
271             //CameraDefFov: 0.7853
272         }
273     }
274 
275     /**
276      * Initialization of modules used within this robot.
277      *
278      * @param bot Necessary parameter for hooking listeners and for sending
279      * commands
280      */
281     @Override
282     public void prepareBot(USAR2004Bot bot)
283     {
284         super.prepareBot(bot);
285 
286         //getWorldView().addEventListener(StateMessage.class, statList);
287 
288         senModule = SensorMasterModule.getModuleInstance(bot);
289         geoModule = GeometryMasterModule.getModuleInstance(bot);
290         confModule = ConfigMasterModule.getModuleInstance(bot);
291         resModule = ResponseModule.getModuleInstance(bot);
292         staModule = StateMasterModule.getModuleInstance(bot);
293 
294         //laserOnly=new SensorSpecificModule<SensorLaser>(bot, SensorLaser.class);
295         //initModule = new InitializeOnceOnStartPoses(bot, "USARBot.Submarine", "P2DX sample robot");
296         //getWorldView().addEventListener(SensorMessage.class, sensorList);
297         //getWorldView().addEventListener(NfoMessage.class, nfoList);
298 
299         //Map<Class, Map<WorldObjectId, IViewable>> allVisible = getWorldView().getAllVisible();
300     }
301     //private NfoBeginMapInfo begin;
302     private NfoStartPoses startPoses;
303     private SensorLaser laserSensor;
304     //private InitializeOnceOnStartPoses initModule;
305     private SensorMasterModule senModule;
306     private GeometryMasterModule geoModule;
307     private ConfigMasterModule confModule;
308     private ResponseModule resModule;
309     private StateMasterModule staModule;
310     private SensorSpecificModule<SensorLaser> laserOnly;
311 
312     public static void main(String[] args)
313     {
314         new USAR2004BotRunner(Submarine.class, "PogamutBotBot", "127.0.0.1", 3000).setMain(true).setLogLevel(Level.WARNING).startAgent();
315     }
316 }