SimpleMulticopterMovement.java 8.33 KB
Newer Older
Julian Zobel's avatar
Julian Zobel committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/*
 * 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/>.
 *
 */

package de.tud.kom.p2psim.impl.topology.movement.aerial;

23

Julian Zobel's avatar
Julian Zobel committed
24
25
26
27
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.Map;
import de.tud.kom.p2psim.api.topology.movement.UAVMovementModel;
28
29
import de.tud.kom.p2psim.impl.energy.components.ActuatorComponent;
import de.tud.kom.p2psim.impl.energy.components.StatefulActuatorComponent;
Julian Zobel's avatar
Julian Zobel committed
30
31
32
33
34
35
import de.tud.kom.p2psim.impl.topology.component.UAVTopologyComponent;
import de.tud.kom.p2psim.impl.topology.util.PositionVector;
import de.tudarmstadt.maki.simonstrator.api.Time;
import de.tudarmstadt.maki.simonstrator.api.uavsupport.callbacks.ReachedLocationCallback;

/**
36
37
38
 * Local movement for UAVs. 
 * This simple movement logic uses straight forward movement with the set speed (up to a max).
 * Energy consumption is based on state actuators.
Julian Zobel's avatar
Julian Zobel committed
39
40
 * 
 * @author Julian Zobel
41
 * @version 1.1, 14.01.2020
Julian Zobel's avatar
Julian Zobel committed
42
43
44
 */
public class SimpleMulticopterMovement implements UAVMovementModel  {

45
	private UAVTopologyComponent topologyComponent;	
46
47
	private double velocity;	
	private double targetVelocity;
Julian Zobel's avatar
Julian Zobel committed
48
	
49
50
	private double maximumHorizontalVelocity;
	private double maximumVerticalVelocity;
Julian Zobel's avatar
Julian Zobel committed
51
	
52
53
54
55
	// TODO currently not used
	private double minimumHorizontalVelocity;
	private double minimumVerticalVelocity;
	
56
57
	private double optimalHorizontalVelocity;
	
Julian Zobel's avatar
Julian Zobel committed
58
	private LinkedList<PositionVector> route = new LinkedList<>();
59
	private Map<PositionVector, ReachedLocationCallback> locationCallbacks = new LinkedHashMap<>();  
60
		
61
	private StatefulActuatorComponent motor;
62
		
63
	public SimpleMulticopterMovement(UAVTopologyComponent topologyComponent, double maximumHorizontalVelocity, double optimalHorizontalVelocity,
64
			double maximumVerticalVelocity, double minimumHorizontalVelocity, double minimumVerticalVelocity) {
65
66
		this.topologyComponent = topologyComponent;		
		this.maximumHorizontalVelocity = maximumHorizontalVelocity;
67
		this.optimalHorizontalVelocity = optimalHorizontalVelocity;
68
		this.maximumVerticalVelocity = maximumVerticalVelocity;
69
70
		this.minimumHorizontalVelocity = minimumHorizontalVelocity;
		this.minimumVerticalVelocity = minimumVerticalVelocity;
71
	}	
Julian Zobel's avatar
Julian Zobel committed
72
73
74
	
	@Override
	public void move(long timeBetweenMovementOperations) {
75
				
76
77
78
		if(motor.isOn() && !route.isEmpty()) {		
		
			PositionVector currentPosition = topologyComponent.getRealPosition();
Julian Zobel's avatar
Julian Zobel committed
79
			
80
81
82
			PositionVector targetPosition = route.getFirst();
			Double distanceToTargetPosition = targetPosition.distanceTo(currentPosition);
							
Julian Zobel's avatar
Julian Zobel committed
83
			// If target point is reached within a 1 meter margin, we remove that point from the list 
84
			if(distanceToTargetPosition < 0.1 || distanceToTargetPosition < velocity)
Julian Zobel's avatar
Julian Zobel committed
85
			{						
86
				route.removeFirst();
Julian Zobel's avatar
Julian Zobel committed
87
				
88
				topologyComponent.updateCurrentLocation(targetPosition); // triggers energy consumption for last distance
89
				velocity = 0;
90
91
92
				motor.useActuator(0);
				locationReached(targetPosition);
				return;
Julian Zobel's avatar
Julian Zobel committed
93
			}
94
95
96
			
			double timefactor = timeBetweenMovementOperations / Time.SECOND;
			
97
			velocity = Math.min(distanceToTargetPosition, targetVelocity);					
98
99
100
101
						
			PositionVector direction = new PositionVector(targetPosition);
			direction.subtract(currentPosition);
			direction.normalize();
102
			topologyComponent.updateCurrentDirection(direction);
103
			direction.multiplyScalar(velocity * timefactor);
Julian Zobel's avatar
Julian Zobel committed
104

105
106
			PositionVector newPosition = new PositionVector(currentPosition);
			newPosition.add(direction);		
Julian Zobel's avatar
Julian Zobel committed
107
			
108
109
110
111
112
113
114
115
			if(velocity <= optimalHorizontalVelocity) {
				motor.useActuator(1.0);
			}
			else {
				motor.useActuator(2.0);
			}
					
					
116
			topologyComponent.updateCurrentLocation(newPosition);					
Julian Zobel's avatar
Julian Zobel committed
117
		}
Julian Zobel's avatar
Bugfix    
Julian Zobel committed
118
119
		else if(motor.isOn()) {
			
120
			if(velocity != 0) {
Julian Zobel's avatar
Bugfix    
Julian Zobel committed
121
122
123
124
125
126
				throw new UnsupportedOperationException("no route but speed not 0?");
			}
			
			PositionVector position = new PositionVector(topologyComponent.getRealPosition());	
			
			if(position.getAltitude() == 0) {
127
				motor.turnOff();
Julian Zobel's avatar
Bugfix    
Julian Zobel committed
128
129
			}
			else {
130
				motor.useActuator(0);
Julian Zobel's avatar
Bugfix    
Julian Zobel committed
131
132
			}
		}
Julian Zobel's avatar
Julian Zobel committed
133
134
135
	}
		
	@Override
136
137
	public void setTargetVelocity(double v_pref) {
		this.targetVelocity = v_pref;		
Julian Zobel's avatar
Julian Zobel committed
138
139
140
	}
	
	@Override
141
142
	public double getCurrentVelocity() {
		return velocity;
Julian Zobel's avatar
Julian Zobel committed
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
	}

	/**
	 * Trigger the callback function, if there is a valid callback 
	 * 
	 * @param position
	 */
	private void locationReached(PositionVector position) {
		if(locationCallbacks.containsKey(position)) {
			locationCallbacks.get(position).reachedLocation();
		}
	}
	
	@Override
	public void setTargetLocation(PositionVector target,
			ReachedLocationCallback reachedLocationCallback) {
		route.clear();
		route.add(target);
		if(reachedLocationCallback != null)
			locationCallbacks.put(target, reachedLocationCallback);
		
	}

	@Override
	public void setTargetLocationRoute(LinkedList<PositionVector> route,
			ReachedLocationCallback reachedLocationCallback) {
		this.route.clear();
		this.route.addAll(route);
		if(reachedLocationCallback != null)
			locationCallbacks.put(route.getLast(), reachedLocationCallback);
	}

	@Override
	public void addTargetLocation(PositionVector target,
			ReachedLocationCallback reachedLocationCallback) {
		route.add(target);
		if(reachedLocationCallback != null)
			locationCallbacks.put(target, reachedLocationCallback);
	}

	@Override
	public LinkedList<PositionVector> getTargetLocations() {
		
		LinkedList<PositionVector> copy = new LinkedList<>();
		for (PositionVector pv : route) {
			copy.add(pv.clone());		
		}
		
		return copy;
	}

	@Override
	public void removeTargetLocations() {
		route.clear();
		locationCallbacks.clear();
	}

200
	@Override
201
202
203
	public double estimatePowerConsumptionWatt(double velocity) {
		
		double wattage = 0;
204
205
		
		if(velocity == 0) {
206
			wattage = motor.estimateEnergyConsumptionWatt(0);
207
		}
208
209
210
211
212
		else if( velocity <= optimalHorizontalVelocity){
			wattage = motor.estimateEnergyConsumptionWatt(1);
		}
		else {
			wattage = motor.estimateEnergyConsumptionWatt(2);
213
214
		}
		
215
		return wattage;
216
	}
217
218
219
220
221
222
223

	@Override
	public void setMotorControl(ActuatorComponent motor) {
		this.motor = (StatefulActuatorComponent) motor;
	}

	@Override
224
225
	public double getVerticalAscentMaxVelocity() {
		return maximumVerticalVelocity;
226
227
228
	}

	@Override
229
230
	public double getHorizontalMaxVelocity() {
		return maximumHorizontalVelocity;
231
	}
232
	
233
	@Override	
234
	public double getHorizontalMinVelocity() {
235
236
		return 0;
	}
237
238
239
240
241
242
243
244
	
	/**
	 * Factory for this movement model
	 * 
	 * @author Julian Zobel
	 * @version 1.0, 14.01.2020
	 */
	public static class Factory implements AerialMovementModelFactory {
245
246
247
248
249
250
		
		private double maximumHorizontalVelocity = 15;
		
		public void setMaximumHorizontalVelocity(double maximumHorizontalVelocity) {
			this.maximumHorizontalVelocity = maximumHorizontalVelocity;
		}
251
252
253
254
255
256
		
		private double optimalHorizontalVelocity = 10;
		
		public void setOptimalHorizontalVelocity(double optimalHorizontalVelocity) {
			this.optimalHorizontalVelocity = optimalHorizontalVelocity;
		}		
257
258
259
260
261
262
263

		private double maximumVerticalVelocity = 5;		
		
		public void setMaximumVerticalVelocity(double maximumVerticalVelocity) {
			this.maximumVerticalVelocity = maximumVerticalVelocity;
		}
		
264
265
266
267
268
269
270
271
272
273
274
275
		private double minimumHorizontalVelocity = 15;
		
		public void setMinimumHorizontalVelocity(double minimumHorizontalVelocity) {
			this.minimumHorizontalVelocity = minimumHorizontalVelocity;
		}
		
		private double minimumVerticalVelocity = 5;		
		
		public void setMinimumVerticalVelocity(double minimumVerticalVelocity) {
			this.minimumVerticalVelocity = minimumVerticalVelocity;
		}
		
276
		public UAVMovementModel createComponent(UAVTopologyComponent topologyComponent) {
277
			return new SimpleMulticopterMovement(topologyComponent, maximumHorizontalVelocity, optimalHorizontalVelocity,
278
					maximumVerticalVelocity, minimumHorizontalVelocity, minimumVerticalVelocity);
279
		}			
280
	}
281
282
283

	@Override
	public double estimateOptimalSpeed() {
284
		return optimalHorizontalVelocity;
285
	}
Julian Zobel's avatar
Julian Zobel committed
286
}