UAVTopologyComponent.java 12.7 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*
 * Copyright (c) 2005-2010 KOM – Multimedia Communications Lab
 *
 * This file is part of PeerfactSim.KOM.
 * 
 * PeerfactSim.KOM 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
 * any later version.
 * 
 * PeerfactSim.KOM 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 PeerfactSim.KOM.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

21
package de.tud.kom.p2psim.impl.topology.component;
22

23
import java.util.LinkedList;
24
25
import java.util.Set;
import de.tud.kom.p2psim.api.common.SimHost;
26
import de.tud.kom.p2psim.api.energy.Battery;
27
28
import de.tud.kom.p2psim.api.energy.ComponentType;
import de.tud.kom.p2psim.api.energy.EnergyModel;
29
import de.tud.kom.p2psim.api.network.SimNetInterface;
30
import de.tud.kom.p2psim.api.topology.Topology;
31
import de.tud.kom.p2psim.api.topology.TopologyComponent;
32
import de.tud.kom.p2psim.api.topology.movement.MovementModel;
33
import de.tud.kom.p2psim.api.topology.movement.SimUAVLocationActuator;
34
35
import de.tud.kom.p2psim.api.topology.movement.UAVMovementModel;
import de.tud.kom.p2psim.api.topology.placement.PlacementModel;
36
import de.tud.kom.p2psim.impl.energy.RechargeableBattery;
37
import de.tud.kom.p2psim.impl.energy.components.ActuatorComponent;
38
39
import de.tud.kom.p2psim.impl.energy.models.AbstractEnergyModel;
import de.tud.kom.p2psim.impl.topology.placement.UAVBasePlacement;
40
import de.tud.kom.p2psim.impl.topology.util.PositionVector;
41
import de.tudarmstadt.maki.simonstrator.api.Monitor;
42
import de.tudarmstadt.maki.simonstrator.api.component.ComponentNotAvailableException;
Julian Zobel's avatar
Julian Zobel committed
43
import de.tudarmstadt.maki.simonstrator.api.component.overlay.OverlayComponent;
44
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.IAttractionPoint;
45
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location;
Julian Zobel's avatar
Julian Zobel committed
46
import de.tudarmstadt.maki.simonstrator.api.uavsupport.callbacks.BaseConnectionCallback;
47
import de.tudarmstadt.maki.simonstrator.api.uavsupport.callbacks.BatteryReplacementCallback;
48
import de.tudarmstadt.maki.simonstrator.api.uavsupport.callbacks.ReachedLocationCallback;
Julian Zobel's avatar
Julian Zobel committed
49
import de.tudarmstadt.maki.simonstrator.api.uavsupport.communication.UAVToBaseInterface;
50

Julian Zobel's avatar
Julian Zobel committed
51
/**
Julian Zobel's avatar
Julian Zobel committed
52
 * Topology component extension providing a broader topology functionality for UAVs
Julian Zobel's avatar
Julian Zobel committed
53
54
55
56
 * 
 * @author Julian Zobel
 * @version 1.0, 06.09.2018
 */
57
public class UAVTopologyComponent extends AbstractTopologyComponent implements SimUAVLocationActuator {
58
	
Julian Zobel's avatar
Julian Zobel committed
59
	public enum UAVstate {OFFLINE, BASE_CONNECTION, BASE_CONNECTION_READY, ACTION, RETURN, CRASHED}
60
	
61
	private UAVMovementModel movement;
62
	
63
64
	private OverlayComponent uavOverlayComponent;
	
Julian Zobel's avatar
Julian Zobel committed
65
66
	protected PositionVector direction;
	
67
	private ActuatorComponent actuator;
68
69
	private RechargeableBattery battery;
	
70
	private UAVstate state = UAVstate.OFFLINE;
71
	private PositionVector baseLocation;
Julian Zobel's avatar
Julian Zobel committed
72
	
Julian Zobel's avatar
Julian Zobel committed
73
74
	private UAVToBaseInterface controllerInterface;
	
75
76
77
78
79
80
81
82
83
	/**
	 * Create a TopologyComponent for the current host.
	 *
	 * @param host
	 * @param topology
	 * @param movementModel
	 */
	public UAVTopologyComponent(SimHost host, Topology topology,
			MovementModel movementModel, PlacementModel placementModel, boolean registerAsInformationProviderInSiS) {
84
		super(host, topology, movementModel, placementModel, registerAsInformationProviderInSiS);		
Julian Zobel's avatar
Julian Zobel committed
85
		direction = new PositionVector(0,-1,0);				
86
87
	}

88
89
90
91
92
93
	@Override
	public void initialize() {		
		super.initialize();
		
		try {
			actuator = getHost().getComponent(EnergyModel.class)
94
					.getComponent(ComponentType.ACTUATOR, ActuatorComponent.class);	
95
			movement.setMotorControl(actuator);
96
97
98
99
100
		} catch (ComponentNotAvailableException e) {
			System.err.println("No Acutator Energy Component was found!");
		}
		
		try {
101
			battery = (RechargeableBattery) getHost().getComponent(AbstractEnergyModel.class).getBattery();
102
103
104
105
				
		} catch (ComponentNotAvailableException e) {
			System.err.println("No Battery Component was found!");
		}
106
		
Julian Zobel's avatar
Julian Zobel committed
107
		// retrieve base location
Julian Zobel's avatar
Julian Zobel committed
108
109
		baseLocation = UAVBasePlacement.base.position.clone();	
		
110
111
	}
	
Julian Zobel's avatar
Julian Zobel committed
112
	private void setState(UAVstate newState) {
113
		this.state = newState;
114
115
		
		// TODO analyzer
116
117
118
		if(Monitor.hasAnalyzer(UAVStatisticAnalyzer.class)) {
			Monitor.getOrNull(UAVStatisticAnalyzer.class).uavSwitchedStates(this, newState);
		}
119
	}
120
			
121
122
123
	public void setUAVComponent(OverlayComponent uavOverlayComponent) {
		this.uavOverlayComponent = uavOverlayComponent;
	}
124
	
125
126
127
128
	public OverlayComponent getUAVComponent() {
		return uavOverlayComponent;
	}

129
130
	@Override
	public double getMinMovementSpeed() {
131
		return movement.getHorizontalMinVelocity();
132
133
134
135
	}

	@Override
	public double getMaxMovementSpeed() {
136
		return movement.getHorizontalMaxVelocity();
137
138
139
140
	}

	@Override
	public double getMovementSpeed() {
141
		return movement.getCurrentVelocity();
142
143
144
145
	}

	@Override
	public void setMovementSpeed(double speed) {
146
		movement.setTargetVelocity(speed);
147
148
149
	}

	@Override
150
	public boolean isActive() {
151
		if(actuator.isOn()) {
152
			return true;
153
		} else {
154
155
156
157
158
			if(state == UAVstate.ACTION || state == UAVstate.RETURN) {
				this.deactivate();
			}
			return false;
		}
159
160
161
	}

	@Override
162
163
	public boolean activate() {		
		if(actuator.turnOn()) {
164
			this.setState(UAVstate.ACTION);			
165
166
167
168
169
			return true;
		}
		else {
			return false;
		}
170
171
172
173
	}

	@Override
	public boolean deactivate() {
174
		actuator.turnOff();
175
				
176
177
178
		if(this.position.getAltitude() != 0) {
			this.setState(UAVstate.CRASHED);		
						
179
180
			uavOverlayComponent.shutdown();	
			shutdownCommunication();
181
182
183
184
			
		} else {
			this.setState(UAVstate.OFFLINE);				
		}				
185
		
186
		return true;
187
188
189
	}

	@Override
190
191
	public PositionVector getCurrentLocation() {
		return position.clone();
192
193
194
	}

	@Override
195
	public double getCurrentBatteryLevel() {
196
		return battery.getCurrentPercentage();
197
	}
198
199
200
	
	@Override
	public double getCurrentBatteryEnergy() {
201
		return battery.getCurrentEnergy();
202
	}
203

204
205
206
	public RechargeableBattery getBattery() {
		return battery;
	}
207
	
208
209
210
211
212
	@Override
	public double getMaximumBatteryCapacity() {
		return battery.getMaximumEnergy();
	}
	
213
214
215
216
217
	@Override
	public UAVMovementModel getUAVMovement() {
		return movement;
	}

Julian Zobel's avatar
Julian Zobel committed
218
219
	@Override
	public void setUAVMovement(UAVMovementModel uavMovement) {
220
		this.movement = uavMovement;		
Julian Zobel's avatar
Julian Zobel committed
221
	}
222

223
	@Override
224
	public Set<IAttractionPoint> getAllAttractionPoints() {
225
226
227
228
229
230
		throw new UnsupportedOperationException();
	}

	@Override
	public void setTargetLocation(PositionVector targetLocation,
			ReachedLocationCallback cb) {
Julian Zobel's avatar
Julian Zobel committed
231
232
		if(!isActive()) return;
		
233
234
235
236
237
238
		movement.setTargetLocation(new PositionVector(targetLocation), cb);		
	}

	@Override
	public void addTargetLocation(PositionVector targetLocation,
			ReachedLocationCallback cb) {
Julian Zobel's avatar
Julian Zobel committed
239
240
		if(!isActive()) return;
		
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
		movement.addTargetLocation(new PositionVector(targetLocation), cb);
	}

	@Override
	public void setTargetLocationRoute(LinkedList<PositionVector> route,
			ReachedLocationCallback cb) {
		LinkedList<PositionVector> positionvectorlist = new LinkedList<>();
		for (Location loc : route) {
			positionvectorlist.add(new PositionVector(loc));
		}
		movement.setTargetLocationRoute(positionvectorlist, cb);
	}

	@Override
	public void removeAllTargetLocations() {
		movement.removeTargetLocations();
	}

	@Override
260
	public void setTargetAttractionPoint(IAttractionPoint targetAttractionPoint) {
261
262
263
264
		throw new UnsupportedOperationException();		
	}

	@Override
265
	public IAttractionPoint getCurrentTargetAttractionPoint() {
266
267
268
269
270
271
272
273
		throw new UnsupportedOperationException();
	}

	@Override
	public LinkedList<PositionVector> getTargetLocations() {
		return movement.getTargetLocations();
	}

274
275
276
	public UAVstate getUAVState() {
		return state;
	}
277
	
Julian Zobel's avatar
Julian Zobel committed
278
279
280
281
282
283
284
285
286
287
288
289
290
	private PositionVector getOverBaseLocation() {
		PositionVector locationOverBase = baseLocation.clone();
		locationOverBase.setAltitude(10);
		
		return locationOverBase;
	}
	
	@Override
	public void returnToBase(double velocity, ReachedLocationCallback cb) {					
		movement.setTargetVelocity(velocity);
		movement.setTargetLocation(getOverBaseLocation(), cb);	
	}

291
	@Override
Julian Zobel's avatar
Julian Zobel committed
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
	public boolean landAtBase(BaseConnectionCallback cb) {
		if(overBaseLocation()) {
			this.setState(UAVstate.RETURN);		
			
			ReachedLocationCallback landedCallback = new ReachedLocationCallback() {
				
				@Override
				public void reachedLocation() {
					deactivate();
					connectToBase(cb);				
				}
			};
			
			movement.setTargetVelocity(5);
			movement.setTargetLocation(baseLocation, landedCallback);
			
			return true;
		}
		else return false;
	}	
312
		
Julian Zobel's avatar
Julian Zobel committed
313
314
315
316
317
318
319
320
321
	@Override
	public boolean startFromBase(ReachedLocationCallback cb) {
		if(this.getCurrentLocation().equals(this.getBaseLocation())
				&& state == UAVstate.BASE_CONNECTION_READY 
				&& activate()) {
			disconnectFromBase();
						
			movement.setTargetVelocity(movement.getVerticalAscentMaxVelocity());
			movement.setTargetLocation(getOverBaseLocation(), cb);
322
			
Julian Zobel's avatar
Julian Zobel committed
323
324
325
			return true;
		}
		else return false;
326
327
		
	}
Julian Zobel's avatar
Julian Zobel committed
328
329
330
331
332
333
334
335
336
	
	private boolean overBaseLocation() {
		if(this.getCurrentLocation().getX() == this.getBaseLocation().getX() 
				&& this.getCurrentLocation().getY() == this.getBaseLocation().getY()) {
			return true;
		}
		else return false;
	}
	
337
		
Julian Zobel's avatar
Julian Zobel committed
338
	private void batteryReplacement(BatteryReplacementCallback cb) {
339
		
340
		if(state != UAVstate.BASE_CONNECTION) {
341
			throw new UnsupportedOperationException("Cannot recharge if not connected to base!");
342
		}
343
		
Julian Zobel's avatar
Julian Zobel committed
344
345
		this.setState(UAVstate.OFFLINE);
		
346
		BaseTopologyComponent base = UAVBasePlacement.base;
347
		base.getCharger().charge(this, cb);
348
	}
349

Julian Zobel's avatar
Julian Zobel committed
350
	public void setControllerInterface(UAVToBaseInterface controllerInterface) {
Julian Zobel's avatar
Julian Zobel committed
351
352
353
		this.controllerInterface = controllerInterface;			
		this.controllerInterface.setDeploymentArea(topology.getWorldDimensions());
		connectToBase(null);
Julian Zobel's avatar
Julian Zobel committed
354
355
	}

Julian Zobel's avatar
Julian Zobel committed
356
357
358
359
360
361
	/**
	 * Connect to the base and initiate a recharge
	 * 
	 * @param cb
	 */
	private void connectToBase(BaseConnectionCallback cb) {
Julian Zobel's avatar
Julian Zobel committed
362
363
364
		BaseTopologyComponent base = UAVBasePlacement.base;
		base.connectUAVToBase(controllerInterface);	
		
Julian Zobel's avatar
Julian Zobel committed
365
366
367
368
		if(cb != null) {			
			cb.successfulConnection();		
		}
				
369
		this.setState(UAVstate.BASE_CONNECTION);		
370
		shutdownCommunication();
Julian Zobel's avatar
Julian Zobel committed
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
		
		// recharge
		if(battery.getCurrentPercentage() <= 75) {
			batteryReplacement(new BatteryReplacementCallback() {

				@Override
				public void rechargeComplete() {
					setState(UAVstate.BASE_CONNECTION_READY);
					if(cb != null) {
						cb.readyForTakeoff();
					}
				}
			});
		}
		else {
			this.setState(UAVstate.BASE_CONNECTION_READY);		
			if(cb != null) {
				cb.readyForTakeoff();
			}
		}
Julian Zobel's avatar
Julian Zobel committed
391
392
	}

Julian Zobel's avatar
Julian Zobel committed
393
394
	
	private void disconnectFromBase() {
395
396
		startCommunication();
		
Julian Zobel's avatar
Julian Zobel committed
397
		BaseTopologyComponent base = UAVBasePlacement.base;
Julian Zobel's avatar
Julian Zobel committed
398
		base.disconnectUAVFromBase(controllerInterface);		
Julian Zobel's avatar
Julian Zobel committed
399
400
	}

401
402
403
404
	private void shutdownCommunication() {
		for (SimNetInterface net : getHost().getNetworkComponent().getSimNetworkInterfaces()) 
			net.goOffline();
	}
Julian Zobel's avatar
Julian Zobel committed
405

406
407
408
409
	private void startCommunication() {
		for (SimNetInterface net : getHost().getNetworkComponent().getSimNetworkInterfaces()) 
			net.goOnline();
	}
410

Julian Zobel's avatar
Julian Zobel committed
411
412
413
414
415
416
417
418
419
	@Override
	public PositionVector getCurrentDirection() {
		return direction;
	}

	@Override
	public void updateCurrentDirection(PositionVector direction) {
		this.direction.set(direction);
	}
420
	
421
	@Override
422
423
	public double estimatePowerConsumptionWatt(double velocity) {
		return movement.estimatePowerConsumptionWatt(velocity);
424
425
426
	}

	@Override
427
428
429
430
431
432
433
434
435
436
437
	public double estimateFlightDistance(double velocity, double batterylevel, double batterythreshold) {
				
		assert batterylevel > batterythreshold;
		assert batterylevel <= 1.0 && batterylevel >= 0.0;
		assert batterythreshold <= 1.0 && batterythreshold >= 0.0;
		
		double availableEnergy = (battery.getMaximumEnergy() * (batterylevel - batterythreshold)) / Battery.uJconverison; // since battery energy is in uJ, conversion in J is required		
		double powerconsumption = estimatePowerConsumptionWatt(velocity); // J/s (or Watt)				
		double distance = (availableEnergy / powerconsumption) * velocity; // d = (E/P)* v [m]
	
		return distance;
438
	}
439
	
440
441
442
443
444
	@Override
	public PositionVector getBaseLocation() {
		return baseLocation.clone();
	}

445
	
446
447
448
449
450
451
452
453
454
455
456
	public static class Factory implements TopologyComponentFactory {

		@Override
		public TopologyComponent createTopologyComponent(SimHost host,
				Topology topology, MovementModel movementModel,
				PlacementModel placementModel,
				boolean registerAsInformationProviderInSiS) {
			return new UAVTopologyComponent(host, topology, movementModel, placementModel, registerAsInformationProviderInSiS);
		}
		
	}
Julian Zobel's avatar
Julian Zobel committed
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473


	@Override
	public UAVstate getState() {
		return state;
	}

	@Override
	public void updateCurrentLocation(Location location) {		
		super.updateCurrentLocation(location);
		
		if(!actuator.isOn() && (state == UAVstate.ACTION || state == UAVstate.RETURN)) {
			this.deactivate();			
		}
		
	}

474
}