Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Simonstrator
PeerfactSim.KOM
Commits
d28bebc4
Commit
d28bebc4
authored
Jun 04, 2019
by
Louis Neumann
Browse files
Merge remote-tracking branch 'origin/jz/dev-metrics' into
jz/bachelor-thesis-louis-neumann
parents
e8d1d98c
be48ff82
Changes
35
Hide whitespace changes
Inline
Side-by-side
src/de/tud/kom/p2psim/api/energy/Battery.java
View file @
d28bebc4
...
...
@@ -31,6 +31,8 @@ package de.tud.kom.p2psim.api.energy;
*/
public
interface
Battery
extends
Cloneable
{
public
static
double
uJconverison
=
1000000
;
/**
* Returns the maximum energy level in uJ.
*
...
...
src/de/tud/kom/p2psim/api/topology/component/ControllableLocationActuator.java
View file @
d28bebc4
...
...
@@ -48,9 +48,19 @@ public interface ControllableLocationActuator extends Actuator {
public
boolean
deactivate
();
public
PositionVector
getCurrentLocation
();
public
PositionVector
getCurrentDirection
();
public
PositionVector
getBaseLocation
();
public
void
updateCurrentDirection
(
PositionVector
direction
);
public
double
getCurrentBatteryLevel
();
public
double
getCurrentBatteryEnergy
();
public
double
getMaximumBatteryCapacity
();
public
LinkedList
<
PositionVector
>
getTargetLocations
();
public
void
setTargetLocation
(
PositionVector
targetLocation
,
ReachedLocationCallback
cb
);
...
...
@@ -76,4 +86,6 @@ public interface ControllableLocationActuator extends Actuator {
public
double
getMaxMovementSpeed
();
public
double
getMovementSpeed
();
public
double
estimatePowerConsumption
(
double
velocity
);
}
src/de/tud/kom/p2psim/api/topology/movement/SimUAVLocationActuator.java
View file @
d28bebc4
...
...
@@ -21,12 +21,13 @@
package
de.tud.kom.p2psim.api.topology.movement
;
import
de.tud.kom.p2psim.api.topology.component.ControllableLocationActuator
;
import
de.tud.kom.p2psim.impl.energy.components.ActuatorEnergyComponent
;
import
de.tud.kom.p2psim.impl.energy.components.StateActuatorEnergyComponent
;
import
de.tud.kom.p2psim.impl.energy.components.StatelessMotorComponent
;
public
interface
SimUAVLocationActuator
extends
SimLocationActuator
,
ControllableLocationActuator
{
public
UAVMovementModel
getUAVMovement
();
public
void
setUAVMovement
(
UAVMovementModel
uavMovement
);
public
ActuatorEnergyComponent
getActuatorEnergyComponent
();
}
src/de/tud/kom/p2psim/api/topology/movement/UAVMovementModel.java
View file @
d28bebc4
...
...
@@ -21,16 +21,23 @@
package
de.tud.kom.p2psim.api.topology.movement
;
import
java.util.LinkedList
;
import
de.tud.kom.p2psim.impl.energy.components.StatelessMotorComponent
;
import
de.tud.kom.p2psim.impl.topology.util.PositionVector
;
import
de.tudarmstadt.maki.simonstrator.api.uavsupport.callbacks.ReachedLocationCallback
;
public
interface
UAVMovementModel
{
public
void
setPreferredCruiseSpeed
(
double
v_pref
);
public
void
setMotorControl
(
StatelessMotorComponent
motor
);
public
void
setPreferredSpeed
(
double
v_pref
);
public
double
getMaxCruiseSpeed
();
public
double
getMinCruiseSpeed
();
public
double
verticalAscentMaxVelocity
();
public
double
horizontalMaxVelocity
();
public
double
getCurrentSpeed
();
public
double
minimumVelocity
();
public
double
estimatePowerConsumption
(
double
velocity
);
public
void
move
(
long
timeBetweenMovementOperations
);
...
...
src/de/tud/kom/p2psim/impl/churn/MaxPeerCountChurnGenerator.java
View file @
d28bebc4
...
...
@@ -114,8 +114,17 @@ public class MaxPeerCountChurnGenerator
@XMLConfigurableConstructor
({
"file"
,
"maxNumberOfNodes"
})
public
MaxPeerCountChurnGenerator
(
String
file
,
int
maxNumberOfNodes
)
{
this
.
maxNumberOfNodes
=
maxNumberOfNodes
;
parseTrace
(
file
);
parseTrace
(
file
);
}
@XMLConfigurableConstructor
({
"churnStart"
,
"maxNumberOfNodes"
,
"burstLength"
})
public
MaxPeerCountChurnGenerator
(
long
churnStart
,
int
maxNumberOfNodes
,
long
burstLength
)
{
this
.
maxNumberOfNodes
=
maxNumberOfNodes
;
churnInfos
.
add
(
new
ChurnInfo
(
churnStart
,
burstLength
,
maxNumberOfNodes
));
this
.
setChurnStart
(
churnStart
);
}
/**
* A class that implements the {@link LifecycleComponent}-interface and can
...
...
src/de/tud/kom/p2psim/impl/energy/components/MotorCharacteristic.java
0 → 100644
View file @
d28bebc4
/*
* 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.energy.components
;
import
de.tudarmstadt.maki.simonstrator.api.util.XMLConfigurableConstructor
;
public
class
MotorCharacteristic
{
private
final
double
thrust
;
private
final
double
current
;
@XMLConfigurableConstructor
({
"thrust"
,
"current"
})
public
MotorCharacteristic
(
double
thrust
,
double
current
)
{
this
.
thrust
=
thrust
;
this
.
current
=
current
;
}
public
double
getCurrent
()
{
return
current
;
}
public
double
getThrust
()
{
return
thrust
;
}
@Override
public
String
toString
()
{
return
"["
+
thrust
+
"N @ "
+
current
+
"A]"
;
}
}
src/de/tud/kom/p2psim/impl/energy/components/ActuatorEnergyComponent.java
→
src/de/tud/kom/p2psim/impl/energy/components/
State
ActuatorEnergyComponent.java
View file @
d28bebc4
...
...
@@ -36,7 +36,7 @@ import de.tudarmstadt.maki.simonstrator.api.Time;
* @author Julian Zobel
* @version 1.0, 11.09.2018
*/
public
class
ActuatorEnergyComponent
implements
EnergyComponent
{
public
class
State
ActuatorEnergyComponent
implements
EnergyComponent
{
/**
* States supported by this energy component
...
...
@@ -53,7 +53,7 @@ public class ActuatorEnergyComponent implements EnergyComponent {
private
double
actuatorLoad
;
public
ActuatorEnergyComponent
(
int
numberOfActuators
,
double
volt
,
double
hoverAmp
,
double
maxAmp
)
{
public
State
ActuatorEnergyComponent
(
int
numberOfActuators
,
double
volt
,
double
hoverAmp
,
double
maxAmp
)
{
OFF
=
new
DefaultEnergyState
(
"OFF"
,
0
);
FLY
=
new
DefaultEnergyState
(
"FLY"
,
numberOfActuators
*
(
hoverAmp
*
volt
)
*
1000000
);
MAX
=
new
DefaultEnergyState
(
"MAX"
,
numberOfActuators
*
(
maxAmp
*
volt
)
*
1000000
);
...
...
src/de/tud/kom/p2psim/impl/energy/components/StatelessMotorComponent.java
0 → 100644
View file @
d28bebc4
/*
* 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.energy.components
;
import
java.util.Comparator
;
import
java.util.LinkedList
;
import
de.tud.kom.p2psim.api.energy.ComponentType
;
import
de.tud.kom.p2psim.api.energy.EnergyComponent
;
import
de.tud.kom.p2psim.api.energy.EnergyEventListener
;
import
de.tud.kom.p2psim.api.energy.EnergyState
;
import
de.tud.kom.p2psim.impl.energy.DefaultEnergyState
;
import
de.tudarmstadt.maki.simonstrator.api.Time
;
/**
* Component for devices that provide thrust, such as electrical motors for UAV propulsion.
* Is configured by {@link MotorCharacteristic}s with a given thrust (N) and a given current (A).
* Values in between given characteristics are calculated by linear interpolation.
*
*
* @author Julian Zobel
* @version 1.0, 05.03.2019
*/
public
class
StatelessMotorComponent
implements
EnergyComponent
{
public
enum
componentState
{
OFF
,
ON
}
private
componentState
state
;
private
EnergyEventListener
energyModel
;
private
long
lastEnergyConsumationTime
;
private
double
volts
;
private
final
double
uJconversionFactor
=
1000000
;
private
final
int
numberOfActuators
;
private
double
thrust
;
private
double
amps
;
private
EnergyState
energyState
;
private
LinkedList
<
MotorCharacteristic
>
characteristics
=
new
LinkedList
<>();
public
StatelessMotorComponent
(
int
numberOfActuators
,
double
volt
)
{
this
.
volts
=
volt
;
this
.
numberOfActuators
=
numberOfActuators
;
this
.
state
=
componentState
.
OFF
;
this
.
lastEnergyConsumationTime
=
Time
.
getCurrentTime
();
thrust
=
0
;
amps
=
0
;
energyState
=
new
DefaultEnergyState
(
"OFF"
,
0
);
}
/**
* Get the maximum thrust provided by this component.
* @return
*/
public
double
getMaxThrust
()
{
return
characteristics
.
getLast
().
getThrust
()
*
numberOfActuators
;
}
/**
* Set the new energy state and calculate the energy consumption from the last state
*/
private
void
setEnergyState
()
{
// set the new energy state
EnergyState
newState
;
if
(
state
==
componentState
.
ON
)
{
newState
=
new
DefaultEnergyState
(
"Actuator"
,
numberOfActuators
*
(
amps
*
volts
)
*
uJconversionFactor
);
}
else
{
newState
=
new
DefaultEnergyState
(
"OFF"
,
0
);
}
// calculate energy consumption for the previous state
long
timeSpentInState
=
Time
.
getCurrentTime
()
-
lastEnergyConsumationTime
;
double
cons
=
calculateEnergyConsumation
(
energyState
,
timeSpentInState
);
energyModel
.
componentConsumedEnergy
(
this
,
cons
);
// set new state
energyState
=
newState
;
lastEnergyConsumationTime
=
Time
.
getCurrentTime
();
}
/**
* Request a given amount of thrust to be provided from this component. If the amount is less than the minimum
* or more than the maximum, the minimum or maximum thrust values, respectively, are enforced.
*
* @param targetThrust
* @return The amount of thrust this component now generates.
*/
public
double
requestThrust
(
double
targetThrust
)
{
if
(
targetThrust
==
0
||
targetThrust
<=
numberOfActuators
*
characteristics
.
getFirst
().
getThrust
())
{
setLoad
(
characteristics
.
getFirst
());
}
else
if
(
targetThrust
>=
numberOfActuators
*
characteristics
.
getLast
().
getThrust
())
{
setLoad
(
characteristics
.
getLast
());
}
else
{
calculateAndSetThrustRelatedAmpereDraw
(
targetThrust
);
}
return
this
.
thrust
;
}
/**
*
* @param targetThrust
* @return The power consumption for the target thrust in uW (micro watt)
*/
public
double
estimatePowerConsumptionWatt
(
double
targetThrust
)
{
if
(
targetThrust
==
0
||
targetThrust
<=
numberOfActuators
*
characteristics
.
getFirst
().
getThrust
())
{
// not allowed
return
Double
.
NaN
;
}
else
if
(
targetThrust
>
numberOfActuators
*
characteristics
.
getLast
().
getThrust
())
{
// not allowed
return
Double
.
NaN
;
}
else
{
double
amps
=
approximateAmpereDraw
(
targetThrust
);
return
numberOfActuators
*
amps
*
volts
;
}
}
/**
* Given an amount of thrust between the minimum and maximum values, the required current
* to provide this amount of thrust is calculated by linear interpolation by the nearest lower
* and upper {@link MotorCharacteristic}s.
*
* @param targetThrust
* @return the approximated ampere draw
*/
private
double
approximateAmpereDraw
(
double
targetThrust
)
{
MotorCharacteristic
lower
=
null
,
upper
=
null
;
// find the lower and upper bounding characteristics
for
(
MotorCharacteristic
ch
:
characteristics
)
{
//
if
(
ch
.
getThrust
()
*
numberOfActuators
==
targetThrust
)
{
return
ch
.
getCurrent
();
}
else
{
// list is sorted, lower bound is the biggest that is lower
if
(
ch
.
getThrust
()
*
numberOfActuators
<
targetThrust
)
{
lower
=
ch
;
}
// the first that is greater is used as upper bound
else
if
(
ch
.
getThrust
()
*
numberOfActuators
>
targetThrust
)
{
upper
=
ch
;
break
;
}
}
}
if
(
upper
==
null
||
lower
==
null
)
{
throw
new
UnsupportedOperationException
(
"Lower or upper bounds cannot be null"
);
}
if
(
upper
.
getThrust
()
*
numberOfActuators
<
targetThrust
||
lower
.
getThrust
()
*
numberOfActuators
>
targetThrust
)
{
throw
new
UnsupportedOperationException
(
"Lower or upper bound do not match"
);
}
/*
* Calculate the approximated current with the upper and lower bounds:
* Amp_approx = Amp_lower + (T_target - T_lower)/(T_upper - T_lower) * (Amp_upper - Amp_lower)
*/
double
delta
=
(
targetThrust
-
(
lower
.
getThrust
()
*
numberOfActuators
))/(
numberOfActuators
*
(
upper
.
getThrust
()
-
lower
.
getThrust
()));
return
lower
.
getCurrent
()
+
delta
*
(
upper
.
getCurrent
()
-
lower
.
getCurrent
());
}
/**
* Approximates the ampere draw required forthe requested thrust
*
* Target thrust should be strictly within the possible thrust limits
*
*/
private
void
calculateAndSetThrustRelatedAmpereDraw
(
double
targetThrust
)
{
double
calculatedAmps
=
approximateAmpereDraw
(
targetThrust
);
setLoad
(
targetThrust
,
calculatedAmps
);
}
private
void
setLoad
(
double
thrust
,
double
amps
)
{
this
.
thrust
=
thrust
;
this
.
amps
=
amps
;
setEnergyState
();
}
private
void
setLoad
(
MotorCharacteristic
ch
)
{
this
.
thrust
=
ch
.
getThrust
();
this
.
amps
=
ch
.
getCurrent
();
setEnergyState
();
}
/**
* Add a {@link MotorCharacteristic} for this motor.
*
* @param c
*/
public
void
addChar
(
MotorCharacteristic
c
)
{
characteristics
.
add
(
c
);
// sort the characteristics starting from low to high thrust
characteristics
.
sort
(
new
Comparator
<
MotorCharacteristic
>()
{
@Override
public
int
compare
(
MotorCharacteristic
o1
,
MotorCharacteristic
o2
)
{
return
(
int
)
(
o1
.
getThrust
()
-
o2
.
getThrust
());
}
});
}
@Override
public
void
eventOccurred
(
Object
content
,
int
type
)
{
// TODO Auto-generated method stub
}
@Override
public
ComponentType
getType
()
{
return
ComponentType
.
ACTUATOR
;
}
@Override
public
boolean
turnOff
()
{
this
.
thrust
=
0
;
this
.
amps
=
0
;
this
.
state
=
componentState
.
OFF
;
setEnergyState
();
return
true
;
}
@Override
public
boolean
turnOn
()
{
if
(
isAvailable
())
{
if
(
this
.
state
!=
componentState
.
ON
)
{
this
.
state
=
componentState
.
ON
;
requestThrust
(
0
);
}
return
true
;
}
return
false
;
}
public
boolean
isAvailable
()
{
if
(
energyModel
.
componentCanBeActivated
(
this
))
{
return
true
;
}
return
false
;
}
@Override
public
boolean
isOn
()
{
if
(
this
.
state
!=
componentState
.
OFF
&&
isAvailable
())
{
return
true
;
}
return
false
;
}
@Override
public
void
setEnergyEventListener
(
EnergyEventListener
listener
)
{
energyModel
=
listener
;
}
public
EnergyState
getCurrentState
()
{
return
energyState
;
}
}
src/de/tud/kom/p2psim/impl/energy/configs/ActuatorConfiguration.java
0 → 100644
View file @
d28bebc4
/*
* 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.energy.configs
;
import
java.util.LinkedList
;
import
de.tud.kom.p2psim.api.common.SimHost
;
import
de.tud.kom.p2psim.api.energy.EnergyConfiguration
;
import
de.tud.kom.p2psim.impl.energy.components.MotorCharacteristic
;
import
de.tud.kom.p2psim.impl.energy.components.StatelessMotorComponent
;
/**
*
*
* @author Julian Zobel
* @version 1.0, 05.03.2019
*/
public
class
ActuatorConfiguration
implements
EnergyConfiguration
<
StatelessMotorComponent
>
{
private
int
numberOfActuators
;
private
double
volt
;
private
LinkedList
<
MotorCharacteristic
>
characteristics
=
new
LinkedList
<>();
@Override
public
StatelessMotorComponent
getConfiguredEnergyComponent
(
SimHost
host
)
{
StatelessMotorComponent
comp
=
new
StatelessMotorComponent
(
numberOfActuators
,
volt
);
for
(
MotorCharacteristic
c
:
characteristics
)
{
comp
.
addChar
(
c
);
}
return
comp
;
}
@Override
public
String
getHelp
()
{
return
"Fix actuator energy consumption config"
;
}
@Override
public
boolean
isWellConfigured
()
{
if
(
numberOfActuators
>=
1
&&
volt
>
0
&&
characteristics
.
size
()
>=
2
)
{
return
true
;
}
return
false
;
}
public
void
setNumberOfActuators
(
int
num
)
{
numberOfActuators
=
num
;
}
public
void
setVolt
(
double
voltage
)
{
this
.
volt
=
voltage
;
}
public
void
setMotorCharacteristic
(
MotorCharacteristic
c
)
{
characteristics
.
add
(
c
);
}
}
src/de/tud/kom/p2psim/impl/energy/configs/ActuatorEnergyConsumptionConfig.java
View file @
d28bebc4
...
...
@@ -22,15 +22,15 @@ package de.tud.kom.p2psim.impl.energy.configs;
import
de.tud.kom.p2psim.api.common.SimHost
;
import
de.tud.kom.p2psim.api.energy.EnergyConfiguration
;
import
de.tud.kom.p2psim.impl.energy.components.ActuatorEnergyComponent
;
import
de.tud.kom.p2psim.impl.energy.components.
State
ActuatorEnergyComponent
;
/**
* Energy Configuration for {@link ActuatorEnergyComponent}s.
* Energy Configuration for {@link
State
ActuatorEnergyComponent}s.
*
* @author Julian Zobel
* @version 1.0, 11.09.2018
*/
public
class
ActuatorEnergyConsumptionConfig
implements
EnergyConfiguration
<
ActuatorEnergyComponent
>
{
public
class
ActuatorEnergyConsumptionConfig
implements
EnergyConfiguration
<
State
ActuatorEnergyComponent
>
{
private
int
numberOfActuators
;
private
double
volt
;
...
...
@@ -38,8 +38,8 @@ public class ActuatorEnergyConsumptionConfig implements EnergyConfiguration<Actu
private
double
flyAmp
;
// in ampere
@Override
public
ActuatorEnergyComponent
getConfiguredEnergyComponent
(
SimHost
host
)
{
return
new
ActuatorEnergyComponent
(
numberOfActuators
,
volt
,
hoverAmp
,
flyAmp
);
public
State
ActuatorEnergyComponent
getConfiguredEnergyComponent
(
SimHost
host
)
{
return
new
State
ActuatorEnergyComponent
(
numberOfActuators
,
volt
,
hoverAmp
,
flyAmp
);
}
@Override
...
...
src/de/tud/kom/p2psim/impl/energy/models/ComponentBasedEnergyModel.java
View file @
d28bebc4
...
...
@@ -25,7 +25,7 @@ import de.tud.kom.p2psim.api.energy.Battery;
import
de.tud.kom.p2psim.api.energy.EnergyComponent
;
import
de.tud.kom.p2psim.api.energy.EnergyEventListener
;
import
de.tud.kom.p2psim.api.network.SimNetInterface
;
import
de.tud.kom.p2psim.impl.energy.components.ActuatorEnergyComponent
;
import
de.tud.kom.p2psim.impl.energy.components.
State
ActuatorEnergyComponent
;
/**
* Energy Model based on multiple exchangeable components. Each component states the amount of consumed energy,
...
...
@@ -60,8 +60,8 @@ public class ComponentBasedEnergyModel extends AbstractEnergyModel implements En
monitorEmptyBattery
();
if
(
component
instanceof
ActuatorEnergyComponent
)
{
((
ActuatorEnergyComponent
)
component
).
turnOff
();
if
(
component
instanceof
State
ActuatorEnergyComponent
)
{
((
State
ActuatorEnergyComponent
)
component
).
turnOff
();
}
/*
...
...
src/de/tud/kom/p2psim/impl/topology/component/UAVStatisticAnalyzer.java
0 → 100644
View file @
d28bebc4
/*
* 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.component
;
import
de.tudarmstadt.maki.simonstrator.api.component.core.MonitorComponent.Analyzer
;
public
interface
UAVStatisticAnalyzer
extends
Analyzer
{
public
void
uavSwitchedStates
(
UAVTopologyComponent
uav
,
UAVTopologyComponent
.
UAVstate
newState
);
}
src/de/tud/kom/p2psim/impl/topology/component/UAVTopologyComponent.java
View file @
d28bebc4
...
...
@@ -22,9 +22,6 @@ package de.tud.kom.p2psim.impl.topology.component;
import
java.util.LinkedList
;
import
java.util.Set
;
import
org.apache.batik.bridge.AbstractSVGGradientElementBridge.Stop
;
import
de.tud.kom.p2psim.api.common.SimHost
;
import
de.tud.kom.p2psim.api.energy.ComponentType
;
import
de.tud.kom.p2psim.api.energy.EnergyModel
;
...
...
@@ -35,15 +32,15 @@ import de.tud.kom.p2psim.api.topology.movement.SimUAVLocationActuator;
import
de.tud.kom.p2psim.api.topology.movement.UAVMovementModel
;
import
de.tud.kom.p2psim.api.topology.placement.PlacementModel
;
import
de.tud.kom.p2psim.impl.energy.RechargeableBattery
;
import
de.tud.kom.p2psim.impl.energy.components.
ActuatorEnergy
Component
;
import
de.tud.kom.p2psim.impl.energy.components.
StatelessMotor
Component
;
import
de.tud.kom.p2psim.impl.energy.models.AbstractEnergyModel
;
import
de.tud.kom.p2psim.impl.topology.placement.UAVBasePlacement
;
import
de.tud.kom.p2psim.impl.topology.util.PositionVector
;
import
de.tudarmstadt.maki.simonstrator.api.Monitor
;
import
de.tudarmstadt.maki.simonstrator.api.component.ComponentNotAvailableException
;
import
de.tudarmstadt.maki.simonstrator.api.component.overlay.OverlayComponent
;
import
de.tudarmstadt.maki.simonstrator.api.component.sensor.location.AttractionPoint
;
import
de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location
;
import
de.tudarmstadt.maki.simonstrator.api.uavsupport.callbacks.BaseConnectedCallback
;
import
de.tudarmstadt.maki.simonstrator.api.uavsupport.callbacks.BaseDisconnectedCallback
;
import
de.tudarmstadt.maki.simonstrator.api.uavsupport.callbacks.BatteryReplacementCallback
;
...
...
@@ -64,7 +61,9 @@ public class UAVTopologyComponent extends AbstractTopologyComponent implements S
private
OverlayComponent
uavOverlayComponent
;
private
ActuatorEnergyComponent
actuator
;
protected
PositionVector
direction
;
private
StatelessMotorComponent
actuator
;
private
RechargeableBattery
battery
;
private
UAVstate
state
=
UAVstate
.
OFFLINE
;
...
...
@@ -82,6 +81,7 @@ public class UAVTopologyComponent extends AbstractTopologyComponent implements S
public
UAVTopologyComponent
(
SimHost
host
,
Topology
topology
,
MovementModel
movementModel
,
PlacementModel
placementModel
,
boolean
registerAsInformationProviderInSiS
)
{
super
(
host
,
topology
,
movementModel
,
placementModel
,
registerAsInformationProviderInSiS
);
direction
=
new
PositionVector
(
0
,-
1
,
0
);
}
@Override
...
...
@@ -90,7 +90,8 @@ public class UAVTopologyComponent extends AbstractTopologyComponent implements S
try
{
actuator
=
getHost
().
getComponent
(
EnergyModel
.
class
)
.
getComponent
(
ComponentType
.
ACTUATOR
,
ActuatorEnergyComponent
.
class
);
.
getComponent
(
ComponentType
.
ACTUATOR
,
StatelessMotorComponent
.
class
);
movement
.
setMotorControl
(
actuator
);
}
catch
(
ComponentNotAvailableException
e
)
{
System
.
err
.
println
(
"No Acutator Energy Component was found!"
);
}
...
...
@@ -108,6 +109,11 @@ public class UAVTopologyComponent extends AbstractTopologyComponent implements S
public
void
setState
(
UAVstate
newState
)
{
this
.
state
=
newState
;
// TODO analyzer
if
(
Monitor
.
hasAnalyzer
(
UAVStatisticAnalyzer
.
class
))
{
Monitor
.
getOrNull
(
UAVStatisticAnalyzer
.
class
).
uavSwitchedStates
(
this
,
newState
);
}
}
public
void
setUAVComponent
(
OverlayComponent
uavOverlayComponent
)
{
...
...
@@ -120,12 +126,12 @@ public class UAVTopologyComponent extends AbstractTopologyComponent implements S
@Override
public
double
getMinMovementSpeed
()
{
return
movement
.
getMinCruiseSpeed
();
return
movement
.
minimumVelocity
();
}
@Override
public
double
getMaxMovementSpeed
()
{
return
movement
.
getMaxCruiseSpeed
();
return
movement
.
horizontalMaxVelocity
();
}
@Override
...
...
@@ -135,14 +141,14 @@ public class UAVTopologyComponent extends AbstractTopologyComponent implements S
@Override
public
void
setMovementSpeed
(
double
speed
)
{
movement
.
setPreferred
Cruise
Speed
(
speed
);
movement
.
setPreferredSpeed
(
speed
);
}
@Override
public
boolean
isActive
()
{
if
(
actuator
.
isOn
())
if
(
actuator
.
isOn
())
{
return
true
;
else
{
}
else
{
if
(
state
==
UAVstate
.
ACTION
||
state
==
UAVstate
.
RETURN
)
{
this
.
deactivate
();
}
...
...
@@ -153,7 +159,7 @@ public class UAVTopologyComponent extends AbstractTopologyComponent implements S
@Override
public
boolean
activate
()
{
if
(
actuator
.
turnOn
())
{
s
tate
=
UAVstate
.
ACTION
;
this
.
setS
tate
(
UAVstate
.
ACTION
);
return
true
;
}
else
{
...
...
@@ -165,18 +171,15 @@ public class UAVTopologyComponent extends AbstractTopologyComponent implements S
public
boolean
deactivate
()
{
actuator
.
turnOff
();
if
(
this
.
position
.
getAltitude
()
!=
0
)
{
state
=
UAVstate
.
CRASHED
;
System
.
err
.
println
(
"UAV was destroyed due to actuator deactivation during flight"
);
if
(
this
.
position
.
getAltitude
()
!=
0
)
{
this
.
setState
(
UAVstate
.
CRASHED
);
uavOverlayComponent
.
shutdown
();
shutdownCommunication
();
}
else
{
state
=
UAVstate
.
OFFLINE
;
}
}
else
{
this
.
setState
(
UAVstate
.
OFFLINE
);
}
return
true
;
}
...
...
@@ -190,6 +193,11 @@ public class UAVTopologyComponent extends AbstractTopologyComponent implements S
public
double
getCurrentBatteryLevel
()
{
return
battery
.
getCurrentPercentage
();
}
@Override
public
double
getCurrentBatteryEnergy
()
{
return
battery
.
getCurrentEnergyLevel
();
}
public
RechargeableBattery
getBattery
()
{
return
battery
;
...
...
@@ -205,11 +213,6 @@ public class UAVTopologyComponent extends AbstractTopologyComponent implements S
this
.
movement
=
uavMovement
;
}
@Override
public
ActuatorEnergyComponent
getActuatorEnergyComponent
()
{
return
actuator
;
}
@Override
public
Set
<
AttractionPoint
>
getAllAttractionPoints
()
{
throw
new
UnsupportedOperationException
();
...
...
@@ -262,8 +265,8 @@ public class UAVTopologyComponent extends AbstractTopologyComponent implements S
}
@Override
public
void
returnToBase
(
ReachedLocationCallback
cb
)
{
this
.
state
=
UAVstate
.
RETURN
;
public
void
returnToBase
(
ReachedLocationCallback
cb
)
{
this
.
s
etS
tate
(
UAVstate
.
RETURN
);
ReachedLocationCallback
returnCallback
=
new
ReachedLocationCallback
()
{
...
...
@@ -274,13 +277,15 @@ public class UAVTopologyComponent extends AbstractTopologyComponent implements S
}
};
movement
.
setPreferredSpeed
(
movement
.
horizontalMaxVelocity
());
movement
.
setTargetLocation
(
baseLocation
,
returnCallback
);
}
public
void
batteryReplacement
(
BatteryReplacementCallback
cb
)
{
if
(
state
!=
UAVstate
.
BASE_CONNECTION
)
if
(
state
!=
UAVstate
.
BASE_CONNECTION
)
{
throw
new
UnsupportedOperationException
(
"Cannot recharge if not connected to base!"
);
}
BaseTopologyComponent
base
=
UAVBasePlacement
.
base
;
base
.
getCharger
().
charge
(
this
,
cb
);
...
...
@@ -298,8 +303,7 @@ public class UAVTopologyComponent extends AbstractTopologyComponent implements S
if
(
cb
!=
null
)
cb
.
successfulConnection
();
this
.
state
=
UAVstate
.
BASE_CONNECTION
;
this
.
setState
(
UAVstate
.
BASE_CONNECTION
);
shutdownCommunication
();
}
...
...
@@ -313,7 +317,6 @@ public class UAVTopologyComponent extends AbstractTopologyComponent implements S
if
(
cb
!=
null
)
cb
.
successfulDisconnection
();
this
.
state
=
UAVstate
.
OFFLINE
;
}
private
void
shutdownCommunication
()
{
...
...
@@ -326,4 +329,31 @@ public class UAVTopologyComponent extends AbstractTopologyComponent implements S
net
.
goOnline
();
}
@Override
public
PositionVector
getCurrentDirection
()
{
return
direction
;
}
@Override
public
void
updateCurrentDirection
(
PositionVector
direction
)
{
this
.
direction
.
set
(
direction
);
}
@Override
public
double
getMaximumBatteryCapacity
()
{
return
battery
.
getMaximumEnergyLevel
();
}
@Override
public
double
estimatePowerConsumption
(
double
velocity
)
{
return
movement
.
estimatePowerConsumption
(
velocity
);
}
@Override
public
PositionVector
getBaseLocation
()
{
return
baseLocation
.
clone
();
}
}
src/de/tud/kom/p2psim/impl/topology/movement/aerial/
SimpleMutl
icopterMovement.java
→
src/de/tud/kom/p2psim/impl/topology/movement/aerial/
Mult
icopterMovement.java
View file @
d28bebc4
...
...
@@ -20,110 +20,235 @@
package
de.tud.kom.p2psim.impl.topology.movement.aerial
;
import
java.util.HashMap
;
import
java.util.LinkedHashMap
;
import
java.util.LinkedList
;
import
java.util.Map
;
import
org.joda.time.tz.ZoneInfoProvider
;
import
org.apache.commons.math3.geometry.Vector
;
import
org.apache.commons.math3.geometry.euclidean.threed.Vector3D
;
import
org.apache.commons.math3.geometry.euclidean.twod.Vector2D
;
import
de.tud.kom.p2psim.api.topology.movement.UAVMovementModel
;
import
de.tud.kom.p2psim.impl.energy.components.StatelessMotorComponent
;
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
;
/**
* Local movement logic specifically designs the movement for multicopter UAVs.
* This simple movement logic uses straight forward movement with the maximum speed available.
*
* @author Julian Zobel
* @version 1.0, 11.09.2018
*/
public
class
SimpleMutlicopterMovement
implements
UAVMovementModel
{
public
class
MulticopterMovement
implements
UAVMovementModel
{
private
UAVTopologyComponent
topologyComponent
;
private
final
double
maxCruiseSpeed
;
private
final
double
minCruiseSpeed
;
private
double
preferredCruiseSpeed
;
private
PositionVector
direction
;
private
double
currentAngleOfAttack
;
private
double
currentSpeed
;
private
double
preferredSpeed
;
private
LinkedList
<
PositionVector
>
route
=
new
LinkedList
<>();
private
Map
<
PositionVector
,
ReachedLocationCallback
>
locationCallbacks
=
new
LinkedHashMap
<>();
// TODO callback interface
private
StatelessMotorComponent
motor
;
public
SimpleMutlicopterMovement
(
UAVTopologyComponent
topologyComponent
,
double
maxCruiseSpeed
,
double
minCruiseSpeed
)
{
private
double
mass
=
1.465
;
// kg
private
final
double
airdensity
=
1.2255
;
// kg/m^3
private
final
double
gravity
=
9.807
;
// m/s^2
private
double
A_top
=
0.245
;
// m^2
private
double
A_front
=
0.04
;
// m^2
private
double
dragCoefficient
=
0.5
;
private
double
maxPitchAngle
=
Math
.
toRadians
(
45
);
// 45° max angle
private
double
descentVelocityMax
=
5
;
// m/s
private
double
maxTurnAngle
=
Math
.
toRadians
(
90
);
// 90° per second turn angle
public
MulticopterMovement
(
UAVTopologyComponent
topologyComponent
)
{
this
.
topologyComponent
=
topologyComponent
;
this
.
maxCruiseSpeed
=
maxCruiseSpeed
;
this
.
minCruiseSpeed
=
minCruiseSpeed
;
this
.
preferredCruiseSpeed
=
this
.
maxCruiseSpeed
;
this
.
direction
=
new
PositionVector
(
0
,
0
);
}
/*
*
*/
public
double
verticalDescentMaxThrust
()
{
// m * g - 0.5 * p * C * A * v^2
return
hoverThrustRequired
()
-
0.5
*
bodyDrag
(
0
,
new
PositionVector
(
0
,
0
,
1
))
*
descentVelocityMax
*
descentVelocityMax
;
}
public
double
verticalAscentMaxAcceleration
()
{
return
(
motor
.
getMaxThrust
()
-
hoverThrustRequired
())
/
mass
;
}
public
double
verticalAscentMaxVelocity
()
{
double
maxThrust
=
motor
.
getMaxThrust
();
return
Math
.
sqrt
(
2.0
*
(
maxThrust
-
hoverThrustRequired
())
/
bodyDrag
(
0
,
new
PositionVector
(
0
,
0
,
1
)));
}
public
double
hoverThrustRequired
()
{
return
mass
*
gravity
;
}
public
double
horizontalMaxVelocity
()
{
@Override
public
void
setPreferredCruiseSpeed
(
double
v_pref
)
{
this
.
preferredCruiseSpeed
=
v_pref
;
double
horizontalThrust
=
horizontalMaxThrust
();
double
maxVelocity
=
Math
.
sqrt
(
(
2.0
*
horizontalThrust
)
/
bodyDrag
(
maxPitchAngle
,
new
PositionVector
(
1
,
0
,
0
)));
return
maxVelocity
;
}
@Override
public
double
getMaxCruiseSpeed
()
{
return
maxCruiseSpeed
;
public
double
horizontalMaxThrust
()
{
// hoverthrust / cos => amount of thrust in horizonal direction with °angle
double
stableAltitudeMaximumTotalThrust
=
hoverThrustRequired
()
/
Math
.
cos
(
maxPitchAngle
);
// fraction of total thrust in horizonal (forward) direction with °angle
double
maximumHorizontalThrustStableAltitude
=
stableAltitudeMaximumTotalThrust
*
Math
.
sin
(
maxPitchAngle
);
return
maximumHorizontalThrustStableAltitude
;
}
@Override
public
double
getMinCruiseSpeed
()
{
return
minCruiseSpeed
;
public
double
bodyDrag
(
double
angleRadians
,
PositionVector
direction
)
{
return
airdensity
*
dragCoefficient
*
areaExposedToDrag
(
angleRadians
,
direction
);
}
@Override
public
double
getCurrentSpeed
()
{
return
currentSpeed
;
public
double
areaExposedToDrag
(
double
angleRadians
,
PositionVector
direction
)
{
Vector2D
v
=
new
Vector2D
(
Math
.
abs
(
direction
.
getX
())
+
Math
.
abs
(
direction
.
getY
()),
Math
.
abs
(
direction
.
getZ
()));
v
=
v
.
normalize
();
double
areaExposedFront
=
v
.
getX
()
*
(
Math
.
sin
(
angleRadians
)
*
A_top
+
Math
.
cos
(
angleRadians
)
*
A_front
);
double
areaExposedTop
=
v
.
getY
()
*
(
Math
.
cos
(
angleRadians
)
*
A_top
+
Math
.
sin
(
angleRadians
)
*
A_front
);
return
areaExposedFront
+
areaExposedTop
;
}
/*
* F_drag [N] = 0.5 * p * C_drag * A * v^2
*/
public
double
currentDrag
()
{
return
0.5
*
bodyDrag
(
currentAngleOfAttack
,
direction
)
*
currentSpeed
*
currentSpeed
;
}
/*
*
*/
@Override
public
void
setMotorControl
(
StatelessMotorComponent
motor
)
{
this
.
motor
=
motor
;
}
@Override
public
void
move
(
long
timeBetweenMovementOperations
)
{
if
(
topologyComponent
.
isActive
()
&&
!
route
.
isEmpty
())
{
PositionVector
current
Position
=
topologyComponent
.
getRealPosition
()
;
if
(
motor
.
isOn
()
&&
!
route
.
isEmpty
())
{
PositionVector
position
=
new
Position
Vector
(
topologyComponent
.
getRealPosition
()
);
PositionVector
targetPosition
=
route
.
getFirst
();
Double
distanceToTargetPosition
=
targetPosition
.
distanceTo
(
currentPosition
);
// If target point is reached within a 1 meter margin, we remove that point from the list
if
(
distanceToTargetPosition
<
0.1
||
distanceToTargetPosition
<
currentSpeed
)
{
route
.
removeFirst
();
topologyComponent
.
getActuatorEnergyComponent
().
useActuator
(
0.5
);
topologyComponent
.
updateCurrentLocation
(
targetPosition
);
// triggers energy consumption for last distance
currentSpeed
=
0
;
topologyComponent
.
getActuatorEnergyComponent
().
useActuator
(
0
);
// now hover
locationReached
(
targetPosition
);
return
;
double
thrust
=
0
;
direction
=
new
PositionVector
(
0
,
0
,
1
);
double
distz
=
100
-
position
.
getZ
();
if
(
distz
<
100
)
{
double
time
=
((
double
)
timeBetweenMovementOperations
)
/
((
double
)
Time
.
SECOND
);
// ASCENSION TO SAFETY HEIGHT
thrust
=
motor
.
requestThrust
(
motor
.
getMaxThrust
());
double
acc
=
((
thrust
-
hoverThrustRequired
())
/
mass
)
-
currentDrag
();
double
speed
=
0
;
if
(
acc
<
0.1
)
{
// normal flight
speed
=
verticalAscentMaxVelocity
();
}
else
{
// acceleration
speed
=
currentSpeed
+
acc
*
time
;
}
System
.
out
.
println
(
"ACCELERATION : "
+
acc
);
System
.
out
.
println
(
"SPEED : "
+
speed
);
//double dist = 0.5 * acc * (timeBetweenMovementOperations / Time.SECOND) * (timeBetweenMovementOperations / Time.SECOND);
double
dist
=
currentSpeed
*
time
;
//double safetydistance = speed
//System.out.println();
position
.
add
(
new
PositionVector
(
0
,
0
,
dist
));
System
.
out
.
println
(
"NEW POSITION : "
+
position
);
topologyComponent
.
updateCurrentLocation
(
position
);
}
else
{
thrust
=
motor
.
requestThrust
(
hoverThrustRequired
());
topologyComponent
.
updateCurrentLocation
(
position
);
}
double
timefactor
=
timeBetweenMovementOperations
/
Time
.
SECOND
;
currentSpeed
=
Math
.
min
(
distanceToTargetPosition
,
preferredCruiseSpeed
);
PositionVector
direction
=
new
PositionVector
(
targetPosition
);
direction
.
subtract
(
currentPosition
);
direction
.
normalize
();
direction
.
multiplyScalar
(
currentSpeed
*
timefactor
);
PositionVector
newPosition
=
new
PositionVector
(
currentPosition
);
newPosition
.
add
(
direction
);
topologyComponent
.
getActuatorEnergyComponent
().
useActuator
(
1
);
topologyComponent
.
updateCurrentLocation
(
newPosition
);
// PositionVector directionToTarget = new PositionVector(route.getFirst());
// directionToTarget.subtract(position);
//
// double distanceToTargetPosition = directionToTarget.getLength();
// // If target point is reached within a 1 meter margin, we remove that point from the list
// if(distanceToTargetPosition < 0.1 || distanceToTargetPosition < currentSpeed)
// {
// route.removeFirst();
//
// topologyComponent.updateCurrentLocation(position);
// currentSpeed = 0;
//
// locationReached(position);
// return;
// }
//
// double timefactor = timeBetweenMovementOperations / Time.SECOND;
//
// currentSpeed = Math.min(distanceToTargetPosition, preferredSpeed);
//
// direction.normalize();
// direction.multiplyScalar(currentSpeed * timefactor);
//
// PositionVector newPosition = new PositionVector(position);
// newPosition.add(direction);
//
// topologyComponent.updateCurrentLocation(newPosition);
}
//System.out.println(Simulator.getFormattedTime(Simulator.getCurrentTime()) + " | " + topologyComponent);
}
@Override
public
void
setPreferredSpeed
(
double
v_pref
)
{
this
.
preferredSpeed
=
v_pref
;
}
@Override
public
double
getCurrentSpeed
()
{
return
currentSpeed
;
}
/**
* Trigger the callback function, if there is a valid callback
*
...
...
@@ -179,7 +304,19 @@ public class SimpleMutlicopterMovement implements UAVMovementModel {
locationCallbacks
.
clear
();
}
@Override
public
double
minimumVelocity
()
{
return
0
;
}
@Override
public
double
estimatePowerConsumption
(
double
velocity
)
{
// TODO Auto-generated method stub
return
0
;
}
}
src/de/tud/kom/p2psim/impl/topology/movement/aerial/SimpleMulticopterMovement.java
0 → 100644
View file @
d28bebc4
/*
* 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
;
import
java.util.LinkedHashMap
;
import
java.util.LinkedList
;
import
java.util.Map
;
import
org.apache.commons.math3.geometry.euclidean.twod.Vector2D
;
import
de.tud.kom.p2psim.api.energy.Battery
;
import
de.tud.kom.p2psim.api.topology.movement.UAVMovementModel
;
import
de.tud.kom.p2psim.impl.energy.components.StatelessMotorComponent
;
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
;
/**
* Local movement logic specifically designs the movement for multicopter UAVs.
* This simple movement logic uses straight forward movement with the maximum speed available.
*
* @author Julian Zobel
* @version 1.0, 11.09.2018
*/
public
class
SimpleMulticopterMovement
implements
UAVMovementModel
{
private
UAVTopologyComponent
topologyComponent
;
private
double
currentAngleOfAttack
;
private
double
currentSpeed
;
private
double
targetSpeed
;
private
LinkedList
<
PositionVector
>
route
=
new
LinkedList
<>();
private
Map
<
PositionVector
,
ReachedLocationCallback
>
locationCallbacks
=
new
LinkedHashMap
<>();
// TODO callback interface
private
StatelessMotorComponent
motor
;
private
double
mass
=
1.465
;
// kg
private
final
double
airdensity
=
1.2045
;
// kg/m^3
private
final
double
gravity
=
9.807
;
// m/s^2
private
double
A_top
=
0.245
;
// m^2
private
double
A_front
=
0.1
;
// m^2
private
double
dragCoefficient
=
0.7
;
private
double
maxPitchAngle
=
Math
.
toRadians
(
60
);
// 45° max angle
private
double
descentVelocityMax
=
5
;
// m/s
private
double
maxTurnAngle
=
Math
.
toRadians
(
90
);
// 90° per second turn angle
public
SimpleMulticopterMovement
(
UAVTopologyComponent
topologyComponent
)
{
this
.
topologyComponent
=
topologyComponent
;
}
boolean
first
=
true
;
@Override
public
void
move
(
long
timeBetweenMovementOperations
)
{
if
(
motor
.
isOn
()
&&
!
route
.
isEmpty
())
{
PositionVector
position
=
new
PositionVector
(
topologyComponent
.
getRealPosition
());
PositionVector
target
=
route
.
getFirst
();
double
distanceToTargetPosition
=
position
.
distanceTo
(
target
);
// If target point is reached within a 1 meter margin, we remove that point from the list
if
(
distanceToTargetPosition
<
0.1
||
distanceToTargetPosition
<
currentSpeed
)
{
target
=
route
.
removeFirst
();
if
(
route
.
isEmpty
())
{
// go to hover mode
topologyComponent
.
updateCurrentLocation
(
target
.
clone
());
currentSpeed
=
0
;
motor
.
requestThrust
(
hoverThrustRequired
());
PositionVector
direction
=
topologyComponent
.
getCurrentDirection
().
clone
();
direction
.
setEntry
(
2
,
0
);
topologyComponent
.
updateCurrentDirection
(
direction
);
locationReached
(
topologyComponent
.
getCurrentLocation
());
return
;
}
else
{
// get to speed
if
(
targetSpeed
>
0
&&
targetSpeed
<
horizontalMaxVelocity
())
{
motor
.
requestThrust
(
estimateRequiredThrust
(
targetSpeed
));
currentSpeed
=
targetSpeed
;
}
else
{
motor
.
requestThrust
(
horizontalMaxVelocityRequiredTotalThrust
());
currentSpeed
=
horizontalMaxVelocity
();
}
long
timeUntilReachedLocation
=
(
long
)
(
distanceToTargetPosition
/
currentSpeed
)
*
Time
.
SECOND
;
target
=
route
.
getFirst
();
PositionVector
directionToTarget
=
new
PositionVector
(
target
);
directionToTarget
.
subtract
(
position
);
double
timefactor
=
timeUntilReachedLocation
/
Time
.
SECOND
;
directionToTarget
.
normalize
();
topologyComponent
.
updateCurrentDirection
(
directionToTarget
.
clone
());
directionToTarget
.
multiplyScalar
(
currentSpeed
*
timefactor
);
PositionVector
newPosition
=
new
PositionVector
(
position
);
newPosition
.
add
(
directionToTarget
);
topologyComponent
.
updateCurrentLocation
(
newPosition
);
if
(
timeUntilReachedLocation
<
timeBetweenMovementOperations
)
{
this
.
move
(
timeBetweenMovementOperations
-
timeUntilReachedLocation
);
}
}
}
else
{
double
timefactor
=
timeBetweenMovementOperations
/
Time
.
SECOND
;
// get to speed
if
(
targetSpeed
>
0
&&
targetSpeed
<
horizontalMaxVelocity
())
{
motor
.
requestThrust
(
estimateRequiredThrust
(
targetSpeed
));
currentSpeed
=
targetSpeed
;
}
else
{
motor
.
requestThrust
(
horizontalMaxVelocityRequiredTotalThrust
());
currentSpeed
=
horizontalMaxVelocity
();
}
PositionVector
directionToTarget
=
new
PositionVector
(
target
);
directionToTarget
.
subtract
(
position
);
directionToTarget
.
normalize
();
if
(
directionToTarget
.
getX
()
!=
0
||
directionToTarget
.
getY
()
!=
0
)
{
topologyComponent
.
updateCurrentDirection
(
directionToTarget
.
clone
());
}
directionToTarget
.
multiplyScalar
(
currentSpeed
*
timefactor
);
PositionVector
newPosition
=
new
PositionVector
(
position
);
newPosition
.
add
(
directionToTarget
);
topologyComponent
.
updateCurrentLocation
(
newPosition
);
}
}
else
if
(
motor
.
isOn
())
{
if
(
currentSpeed
!=
0
)
{
throw
new
UnsupportedOperationException
(
"no route but speed not 0?"
);
}
PositionVector
position
=
new
PositionVector
(
topologyComponent
.
getRealPosition
());
if
(
position
.
getAltitude
()
==
0
)
{
motor
.
requestThrust
(
0
);
}
else
{
motor
.
requestThrust
(
hoverThrustRequired
());
}
}
}
/*
*
*/
public
double
verticalDescentMaxThrust
()
{
// m * g - 0.5 * p * C * A * v^2
return
hoverThrustRequired
()
-
0.5
*
bodyDrag
(
0
,
new
PositionVector
(
0
,
0
,
1
))
*
descentVelocityMax
*
descentVelocityMax
;
}
public
double
verticalAscentMaxAcceleration
()
{
return
(
motor
.
getMaxThrust
()
-
hoverThrustRequired
())
/
mass
;
}
public
double
verticalAscentMaxVelocity
()
{
double
maxThrust
=
motor
.
getMaxThrust
();
return
Math
.
sqrt
(
2.0
*
(
maxThrust
-
hoverThrustRequired
())
/
bodyDrag
(
0
,
new
PositionVector
(
0
,
0
,
1
)));
}
public
double
hoverThrustRequired
()
{
return
mass
*
gravity
;
}
public
double
horizontalMaxVelocity
()
{
double
horizontalThrust
=
horizontalComponentMaxThrust
();
double
maxVelocity
=
Math
.
sqrt
(
(
2.0
*
horizontalThrust
)
/
bodyDrag
(
maxPitchAngle
,
new
PositionVector
(
1
,
0
,
0
)));
return
maxVelocity
;
}
public
double
horizontalComponentMaxThrust
()
{
// hoverthrust / cos => amount of thrust in horizonal direction with °angle
double
stableAltitudeMaximumTotalThrust
=
horizontalMaxVelocityRequiredTotalThrust
();
// fraction of total thrust in horizonal (forward) direction with °angle
double
maximumHorizontalThrustStableAltitude
=
stableAltitudeMaximumTotalThrust
*
Math
.
sin
(
maxPitchAngle
);
return
maximumHorizontalThrustStableAltitude
;
}
public
double
horizontalMaxVelocityRequiredTotalThrust
()
{
return
hoverThrustRequired
()
/
Math
.
cos
(
maxPitchAngle
);
}
public
double
bodyDrag
(
double
angleRadians
,
PositionVector
direction
)
{
return
airdensity
*
dragCoefficient
*
areaExposedToDrag
(
angleRadians
,
direction
);
}
public
double
areaExposedToDrag
(
double
angleRadians
,
PositionVector
direction
)
{
Vector2D
v
=
new
Vector2D
(
Math
.
abs
(
direction
.
getX
())
+
Math
.
abs
(
direction
.
getY
()),
Math
.
abs
(
direction
.
getZ
()));
v
=
v
.
normalize
();
double
areaExposedFront
=
v
.
getX
()
*
(
Math
.
sin
(
angleRadians
)
*
A_top
+
Math
.
cos
(
angleRadians
)
*
A_front
);
double
areaExposedTop
=
v
.
getY
()
*
(
Math
.
cos
(
angleRadians
)
*
A_top
+
Math
.
sin
(
angleRadians
)
*
A_front
);
return
areaExposedFront
+
areaExposedTop
;
}
/*
* F_drag [N] = 0.5 * p * C_drag * A * v^2
*/
public
double
currentDrag
()
{
return
0.5
*
bodyDrag
(
currentAngleOfAttack
,
topologyComponent
.
getCurrentDirection
())
*
currentSpeed
*
currentSpeed
;
}
/**
* Calculate the drag induced on the UAV with a given velocity and an angle of attack (in radians) moving forward horizontally.
*
* @param velocity
* @param angleInRadians
* @return
*/
private
double
forwardDrag
(
double
velocity
,
double
angleInRadians
)
{
return
0.5
*
bodyDrag
(
angleInRadians
,
new
PositionVector
(
1
,
0
,
0
))
*
velocity
*
velocity
;
}
/*
*
*/
@Override
public
void
setMotorControl
(
StatelessMotorComponent
motor
)
{
this
.
motor
=
motor
;
}
@Override
public
void
setPreferredSpeed
(
double
v_pref
)
{
this
.
targetSpeed
=
v_pref
;
}
@Override
public
double
getCurrentSpeed
()
{
return
currentSpeed
;
}
/**
* 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
();
}
@Override
public
double
minimumVelocity
()
{
return
minimumHorizontalVelocity
();
}
public
double
minimumHorizontalVelocity
()
{
return
Math
.
sqrt
(
2
*
hoverThrustRequired
()
*
Math
.
tan
(
Math
.
toRadians
(
0.25
))
/
bodyDrag
(
Math
.
toRadians
(
0.25
),
new
PositionVector
(
1
,
0
,
0
)));
}
@Override
public
double
estimatePowerConsumption
(
double
velocity
)
{
if
(
velocity
==
0
)
{
return
motor
.
estimatePowerConsumptionWatt
(
hoverThrustRequired
());
}
else
if
(
velocity
>
horizontalMaxVelocity
())
{
return
-
1
;
}
else
if
(
velocity
<
minimumHorizontalVelocity
())
{
return
-
1
;
}
else
{
double
estimateAngle
=
estimatePitchAngleForVelocity
(
velocity
);
double
estimatedDrag
=
forwardDrag
(
velocity
,
estimateAngle
);
double
requiredThrust
=
Math
.
sqrt
(
hoverThrustRequired
()
*
hoverThrustRequired
()
+
estimatedDrag
*
estimatedDrag
);
double
wattage
=
motor
.
estimatePowerConsumptionWatt
(
requiredThrust
);
return
wattage
;
}
}
public
double
estimateRequiredThrust
(
double
velocity
)
{
if
(
velocity
==
0
)
{
return
motor
.
estimatePowerConsumptionWatt
(
hoverThrustRequired
());
}
else
if
(
velocity
>
horizontalMaxVelocity
())
{
return
-
1
;
}
else
if
(
velocity
<
minimumHorizontalVelocity
())
{
return
-
1
;
}
else
{
double
estimateAngle
=
estimatePitchAngleForVelocity
(
velocity
);
double
estimatedDrag
=
forwardDrag
(
velocity
,
estimateAngle
);
double
requiredThrust
=
Math
.
sqrt
(
hoverThrustRequired
()
*
hoverThrustRequired
()
+
estimatedDrag
*
estimatedDrag
);
return
requiredThrust
;
}
}
/**
* Estimate the pitch angle (angle of attack) required to get the target velocity.
* Angle precision is 1/4 degree.
*
* @param velocity
* @return
*/
private
double
estimatePitchAngleForVelocity
(
double
velocity
)
{
int
low
=
0
;
int
high
=
Integer
.
MAX_VALUE
;
double
vsquared
=
(
velocity
*
velocity
);
for
(
int
i
=
0
;
i
<=
((
int
)
Math
.
toDegrees
(
maxPitchAngle
));
i
++)
{
double
v2
=
2
*
hoverThrustRequired
()
*
Math
.
tan
(
Math
.
toRadians
(
i
))
/
bodyDrag
(
Math
.
toRadians
(
i
),
new
PositionVector
(
1
,
0
,
0
));
if
(
v2
>
vsquared
&&
i
<
high
)
{
high
=
i
;
}
else
if
(
v2
<
vsquared
&&
i
>=
low
)
{
low
=
i
;
}
else
if
(
v2
==
vsquared
)
{
return
Math
.
toRadians
(
i
);
}
}
if
(
high
<
Integer
.
MAX_VALUE
)
{
double
lo
=
low
;
double
hi
=
high
;
double
nearest
=
-
1
;
double
nearestDiff
=
Double
.
MAX_VALUE
;
double
step
=
(
hi
-
lo
)
/
4
;
for
(
int
i
=
0
;
i
<
4
;
i
++)
{
double
d
=
lo
+
i
*
step
;
double
v2
=
2
*
hoverThrustRequired
()
*
Math
.
tan
(
Math
.
toRadians
(
d
))
/
bodyDrag
(
Math
.
toRadians
(
d
),
new
PositionVector
(
1
,
0
,
0
));
double
diff
=
Math
.
abs
(((
velocity
*
velocity
)
-
v2
));
if
(
diff
<
nearestDiff
||
(
lo
==
0
&&
i
==
1
))
{
nearestDiff
=
diff
;
nearest
=
d
;
}
}
return
Math
.
toRadians
(
nearest
);
}
return
maxPitchAngle
;
}
}
src/de/tud/kom/p2psim/impl/topology/movement/modularosm/ModularMovementModel.java
View file @
d28bebc4
...
...
@@ -158,10 +158,7 @@ public class ModularMovementModel implements MovementModel, EventHandler, Attrac
*/
localMovementStrategy
.
setScaleFactor
(
timeBetweenMoveOperation
/
(
double
)
Time
.
SECOND
);
List
<
AttractionPoint
>
attractionPoints
=
attractionGenerator
.
getAttractionPoints
();
transition
.
setAttractionPoints
(
attractionPoints
);
transition
.
addAttractionAssignmentListener
(
this
);
// This adds the mobile hosts (smartphones/users) to the transition
...
...
@@ -197,13 +194,7 @@ public class ModularMovementModel implements MovementModel, EventHandler, Attrac
public
AttractionPoint
getTargetLocation
(
SimLocationActuator
actuator
)
{
return
transition
.
getAssignment
(
actuator
);
}
@Override
public
Set
<
AttractionPoint
>
getAllAttractionPoints
()
throws
UnsupportedOperationException
{
return
transition
.
getAllAttractionPoints
();
}
private
void
checkConfiguration
()
{
if
(
localMovementStrategy
==
null
)
{
throw
new
ConfigurationException
(
...
...
@@ -362,6 +353,6 @@ public class ModularMovementModel implements MovementModel, EventHandler, Attrac
* @return
*/
public
List
<
AttractionPoint
>
getAttractionPoints
()
{
return
new
Vector
<
AttractionPoint
>(
transition
.
getAllA
ttractionPoints
()
);
return
new
Vector
<
AttractionPoint
>(
IAttractionGenerator
.
a
ttractionPoints
);
}
}
src/de/tud/kom/p2psim/impl/topology/movement/modularosm/ModularMultiTypeMovementModel.java
View file @
d28bebc4
...
...
@@ -78,8 +78,7 @@ public class ModularMultiTypeMovementModel extends ModularMovementModel
suppressListenerNotify
=
true
;
for
(
ITransitionStrategy
strategy
:
supportedTransitions
.
values
())
{
strategy
.
setAttractionPoints
(
transition
.
getAllAttractionPoints
());
{
strategy
.
addAttractionAssignmentListener
(
this
);
for
(
SimLocationActuator
ms
:
moveableHosts
)
{
strategy
.
addComponent
(
ms
);
...
...
src/de/tud/kom/p2psim/impl/topology/movement/modularosm/attraction/BasicAttractionPoint.java
View file @
d28bebc4
...
...
@@ -2,6 +2,7 @@ package de.tud.kom.p2psim.impl.topology.movement.modularosm.attraction;
import
de.tud.kom.p2psim.impl.topology.util.PositionVector
;
import
de.tudarmstadt.maki.simonstrator.api.component.sensor.location.AttractionPoint
;
import
de.tudarmstadt.maki.simonstrator.api.util.XMLConfigurableConstructor
;
/**
* A basic attraction point, as simple as it can get. Really just a named location
...
...
@@ -18,7 +19,11 @@ public class BasicAttractionPoint extends PositionVector implements AttractionPo
this
.
name
=
name
;
}
@XMLConfigurableConstructor
({
"name"
,
"x"
,
"y"
})
public
BasicAttractionPoint
(
String
name
,
double
x
,
double
y
)
{
this
(
name
,
new
PositionVector
(
x
,
y
));
}
@Override
public
String
getName
()
{
return
name
;
...
...
src/de/tud/kom/p2psim/impl/topology/movement/modularosm/attraction/ConfigAttractionGenerator.java
View file @
d28bebc4
...
...
@@ -19,10 +19,7 @@
*/
package
de.tud.kom.p2psim.impl.topology.movement.modularosm.attraction
;
import
java.util.LinkedList
;
import
java.util.List
;
import
de.tudarmstadt.maki.simonstrator.api.component.sensor.location.AttractionPoint
;
/**
...
...
@@ -33,15 +30,14 @@ import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Attraction
*/
public
class
ConfigAttractionGenerator
implements
IAttractionGenerator
{
private
final
List
<
AttractionPoint
>
points
=
new
LinkedList
<>();
@Override
public
List
<
AttractionPoint
>
getAttractionPoints
()
{
return
p
oints
;
return
attractionP
oints
;
}
public
void
setAttractionPoint
(
AttractionPoint
point
)
{
this
.
p
oints
.
add
(
point
);
attractionP
oints
.
add
(
point
);
}
}
src/de/tud/kom/p2psim/impl/topology/movement/modularosm/attraction/ConfigDynamicAttractionGenerator.java
0 → 100644
View file @
d28bebc4
/*
* 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.modularosm.attraction
;
import
java.util.LinkedList
;
import
java.util.List
;
import
java.util.Random
;
import
de.tud.kom.p2psim.api.scenario.ConfigurationException
;
import
de.tud.kom.p2psim.api.topology.Topology
;
import
de.tud.kom.p2psim.impl.topology.util.PositionVector
;
import
de.tudarmstadt.maki.simonstrator.api.Binder
;
import
de.tudarmstadt.maki.simonstrator.api.Event
;
import
de.tudarmstadt.maki.simonstrator.api.EventHandler
;
import
de.tudarmstadt.maki.simonstrator.api.Randoms
;
import
de.tudarmstadt.maki.simonstrator.api.component.sensor.location.AttractionPoint
;
import
de.tudarmstadt.maki.simonstrator.api.util.XMLConfigurableConstructor
;
/**
* Implementation of the interface {@link AttractionGenerator}.
*
* @author Julian Zobel
* @version 1.0, April 2019
*/
public
class
ConfigDynamicAttractionGenerator
implements
IAttractionGenerator
{
private
LinkedList
<
TemporalAttractionPoint
>
allAPs
=
new
LinkedList
<>();
@Override
public
List
<
AttractionPoint
>
getAttractionPoints
()
{
return
attractionPoints
;
}
public
void
setAttractionPoint
(
TemporalAttractionPoint
ap
)
{
allAPs
.
add
(
ap
);
Event
.
scheduleWithDelay
(
ap
.
getPlacementTime
(),
new
EventHandler
()
{
@Override
public
void
eventOccurred
(
Object
content
,
int
type
)
{
placeAP
(
ap
);
}
},
null
,
0
);
}
private
void
placeAP
(
TemporalAttractionPoint
ap
)
{
attractionPoints
.
add
(
ap
);
Event
.
scheduleWithDelay
(
ap
.
getRemovalTime
(),
new
EventHandler
()
{
@Override
public
void
eventOccurred
(
Object
content
,
int
type
)
{
removeAP
(
ap
);
}
},
null
,
0
);
}
private
void
removeAP
(
TemporalAttractionPoint
ap
)
{
attractionPoints
.
remove
(
ap
);
}
}
Prev
1
2
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment