-
Notifications
You must be signed in to change notification settings - Fork 59
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(charging): provide the charging stations within a certain area #446
base: main
Are you sure you want to change the base?
feat(charging): provide the charging stations within a certain area #446
Conversation
...n/java/org/eclipse/mosaic/fed/application/ambassador/util/EventNicenessPriorityRegister.java
Outdated
Show resolved
Hide resolved
...n/java/org/eclipse/mosaic/fed/application/ambassador/util/EventNicenessPriorityRegister.java
Outdated
Show resolved
Hide resolved
.../main/java/org/eclipse/mosaic/interactions/electricity/ChargingStationDiscoveryResponse.java
Outdated
Show resolved
Hide resolved
} | ||
|
||
@Serial | ||
private static final long serialVersionUID = 1L; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we have the serial number here? If it's an interaction-specific thing, why don't we use it in the response as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interaction
implements Serializable
, if we would do distributed simulation in some way or another and serialize/deserialize interactions between remote hosts, this UID would be used to assure that all sides have the same class version loaded. When adding new Interaction
s giving a serialVersionUID
of 1 is good, indicating version 1.
Now what we should consider though is that we update this ID whenever we change Interaction
s in a meaningful manner.
(see https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/io/Serializable.html)
I hope this suffices as a explanation 😅
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-
A specific version is needed especially when storing the serialized objects in files or databases and reading them later. Then the version plays a crucial role to determine if a previously stored object is compatible for deserialization or not. Since we don't do such things, we decided long ago that we use
1
always and everywhere where we implementSerializable
. -
We transfer interactions between PHABMACS and MOSAIC by using this object-serialization, thus we need to implement the
Serializable
interface for all interactions, and for all objects which are used by interactions. Nevertheless, since we serialize/deserialize the objects just for the transport from/to PHABMACS, we don't need to care about versioning, thus using version1
again everywhere.
...ation/src/main/java/org/eclipse/mosaic/fed/application/ambassador/ApplicationAmbassador.java
Outdated
Show resolved
Hide resolved
.tiles | ||
/logs/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should not be necessary, please remove
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@iwillitried yes, there is another .gitignore
in mosaic-starter which ignores the logs
directory. That should suffice and you can remove the /logs/
entry here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is still not resolved!
.../main/java/org/eclipse/mosaic/fed/application/ambassador/simulation/ElectricVehicleUnit.java
Outdated
Show resolved
Hide resolved
} | ||
|
||
@Serial | ||
private static final long serialVersionUID = 1L; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interaction
implements Serializable
, if we would do distributed simulation in some way or another and serialize/deserialize interactions between remote hosts, this UID would be used to assure that all sides have the same class version loaded. When adding new Interaction
s giving a serialVersionUID
of 1 is good, indicating version 1.
Now what we should consider though is that we update this ID whenever we change Interaction
s in a meaningful manner.
(see https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/io/Serializable.html)
I hope this suffices as a explanation 😅
.../main/java/org/eclipse/mosaic/interactions/electricity/ChargingStationDiscoveryResponse.java
Outdated
Show resolved
Hide resolved
.../main/java/org/eclipse/mosaic/interactions/electricity/ChargingStationDiscoveryResponse.java
Outdated
Show resolved
Hide resolved
.../main/java/org/eclipse/mosaic/fed/application/app/api/os/ElectricVehicleOperatingSystem.java
Outdated
Show resolved
Hide resolved
...n/java/org/eclipse/mosaic/fed/application/ambassador/util/EventNicenessPriorityRegister.java
Outdated
Show resolved
Hide resolved
...ic-objects/src/main/java/org/eclipse/mosaic/lib/objects/electricity/ChargingStationData.java
Outdated
Show resolved
Hide resolved
.../main/java/org/eclipse/mosaic/fed/application/app/api/os/ElectricVehicleOperatingSystem.java
Outdated
Show resolved
Hide resolved
...pse/mosaic/fed/application/ambassador/simulation/electric/objects/ChargingStationObject.java
Outdated
Show resolved
Hide resolved
...pse/mosaic/fed/application/ambassador/simulation/electric/objects/ChargingStationObject.java
Show resolved
Hide resolved
...pse/mosaic/fed/application/ambassador/simulation/electric/providers/ChargingStationTree.java
Outdated
Show resolved
Hide resolved
...pse/mosaic/fed/application/ambassador/simulation/electric/providers/ChargingStationTree.java
Outdated
Show resolved
Hide resolved
public class ChargingStationTree extends ChargingStationIndex { | ||
private final int bucketSize; | ||
|
||
private KdTree<ChargingStationObject> chargingStationTree; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't find the code where this Tree is updated... can you help me? The tree should be updated (= take all data from indexedChargingStations and put it into the tree) latest every time before a search is issued?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In my understanding, the Tree uses the object references provided by the indexedChargingStations
class variable. The tree just points at these objects
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, maybe the tree uses the references, this would mean that you continue to have a correct behavior even when CS data is updated.
But as I read the code, you start to have a wrong behavior when CS stations are added or removed.
The code how it is written now has following assumptions:
- All
addChargingStation
calls are done before the firstupdateChargingStation
call - You have at least one
updateChargingStation
call before the first "find in tree" call.
Both are things that might work now, but you cannot assume for the future!
I propose the following, which does not blow up the performance:
- Firstly, write tests, which show that the current code is not working as expected. This way we can prevent regressions in the future.
- Set the flag
recreateTree = true
insideadd
(and theoretically insideremove
) - On every search call, check if you need to recreate the tree. If
recreateTree==true
then build the tree new, and reset the flag to false. - Make sure in a test, that a call to
update
is correctly shown in the tree later
Please create new bug-issues in gitlab for the code parts where you copied this behavior from.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- The KD-Tree implementation used here is not designed to have objects added or removed after initialization, which maybe is a different problem.
- Also as far as I see it, we don't actually need to ever update anything in this tree as for all intents and purposes we are just interested in the position and id of the charging stations, which is already contained within the registration.
- In the traffic light tree we used the updateTrafficLights as a hook to initialize the tree (which is hacky in the first place), as we can be sure the all traffic light registrations have been received before the first update. I'm not sure this can be applied for the charging stations as well. However, I'm not certain how we can know if all charging station registrations have been received. 🤷
- If we actually see the requirement to recreate the tree, we should use a different data structure as recreation scales really poorly.
...n/java/org/eclipse/mosaic/fed/application/ambassador/util/EventNicenessPriorityRegister.java
Outdated
Show resolved
Hide resolved
} | ||
|
||
@Override | ||
public void onChargingStationUpdate() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know that for e.g. TrafficLightTree this does not exist, but please add tests for the functions in ChargingStationIndex and ChargingStationTree
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please check if the test ApplicationAmbassadorTest.processInteraction_ChargingStationRegistration()
is enough or if we need an explicit test for updating the data of the object
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How I read the processInteraction_ChargingStationRegistration
it just shows that the interaction is processed without error, but you don't even have a check which looks if this add
is executed correctly, and if you can then find/search/update the CS later.
So no, unfortunately you have to add more specific and detailed testing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes we should have a separate Test for the ChargingStationTree.
The SimplePerceptionModule Test contains some implicit testing of the indexes, however I agree we should also have separate tests for all perception indexes.
- Merged contents of ChargingStationTree into ChargingStationIndex - ChargingStationIndex is not abstract anymore - small changes regarding function naming and removal of empty lines
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor changes required. Also, please check if all unit tests are green, currently, ApplicationAmbassadorTest.processInteraction_ChargingStationRegistration
fails
.setChargingStationData(chargingStationData); | ||
} | ||
|
||
public List<ChargingStationObject>getChargingStationsInCircle(GeoCircle circle) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code style: missing space before method name
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
public void onChargingStationUpdate() { | ||
if (chargingStationTree == null) { // initialize before first update is called | ||
List<ChargingStationObject> allChargingStations = new ArrayList<>(indexedChargingStations.values()); | ||
chargingStationTree = new KdTree<>(new SpatialObjectAdapter<>(), allChargingStations, bucketSize); | ||
treeTraverser = new SpatialTreeTraverser.InRadius<>(); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this need to be public? I would make that private, rename it to initSearchTree()
and move it right below updateChargingStation
method where it is needed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
public void initialize() { | ||
// initialization at first update | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we have this method if we don't do anything here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed it
public List<ChargingStationData> getChargingStationsInArea(GeoCircle searchArea) { | ||
return SimulationKernel.SimulationKernel.getChargingStationIndex().getChargingStationsInCircle(searchArea) | ||
.stream().map(ChargingStationObject::getChargingStationData) | ||
.collect(Collectors.toList()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use toList()
instead of .collect(Collectors.toList());
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
} | ||
|
||
return this.chargingStationIndex; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
code style: missing blank line after this method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
…ingStationRegistration(...)
import java.util.List; | ||
import java.util.Map; | ||
|
||
public class ChargingStationIndex { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After merging Index and Tree, I think we should stick with naming "Tree". If I merge the two files from "Car extends Vehicle" then also what remains is rather a "Car" than a "Vehicle".
public class ChargingStationTree extends ChargingStationIndex { | ||
private final int bucketSize; | ||
|
||
private KdTree<ChargingStationObject> chargingStationTree; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, maybe the tree uses the references, this would mean that you continue to have a correct behavior even when CS data is updated.
But as I read the code, you start to have a wrong behavior when CS stations are added or removed.
The code how it is written now has following assumptions:
- All
addChargingStation
calls are done before the firstupdateChargingStation
call - You have at least one
updateChargingStation
call before the first "find in tree" call.
Both are things that might work now, but you cannot assume for the future!
I propose the following, which does not blow up the performance:
- Firstly, write tests, which show that the current code is not working as expected. This way we can prevent regressions in the future.
- Set the flag
recreateTree = true
insideadd
(and theoretically insideremove
) - On every search call, check if you need to recreate the tree. If
recreateTree==true
then build the tree new, and reset the flag to false. - Make sure in a test, that a call to
update
is correctly shown in the tree later
Please create new bug-issues in gitlab for the code parts where you copied this behavior from.
} | ||
|
||
@Override | ||
public void onChargingStationUpdate() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How I read the processInteraction_ChargingStationRegistration
it just shows that the interaction is processed without error, but you don't even have a check which looks if this add
is executed correctly, and if you can then find/search/update the CS later.
So no, unfortunately you have to add more specific and detailed testing.
.tiles | ||
/logs/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is still not resolved!
@@ -368,6 +376,9 @@ private void process(final ServerRegistration serverRegistration) { | |||
|
|||
private void process(final ChargingStationRegistration chargingStationRegistration) { | |||
UnitSimulator.UnitSimulator.registerChargingStation(chargingStationRegistration); | |||
String id = chargingStationRegistration.getMapping().getName(); | |||
GeoPoint position = chargingStationRegistration.getMapping().getPosition(); | |||
SimulationKernel.SimulationKernel.chargingStationIndex.addChargingStation(id, position); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use SimulationKernel.SimulationKernel.getChargingStationIndex()
here
@@ -449,6 +460,8 @@ private void process(final ChargingStationUpdate chargingStationUpdate) { | |||
final AbstractSimulationUnit simulationUnit = | |||
UnitSimulator.UnitSimulator.getUnitFromId(chargingStationData.getName()); | |||
|
|||
SimulationKernel.SimulationKernel.chargingStationIndex.updateChargingStation(chargingStationUpdate.getUpdatedChargingStation()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use SimulationKernel.SimulationKernel.getChargingStationIndex()
here.
Also why don't you just use the chargingStationData
as input declared in line 459?
@@ -458,6 +471,7 @@ private void process(final ChargingStationUpdate chargingStationUpdate) { | |||
chargingStationData, | |||
EventNicenessPriorityRegister.UPDATE_CHARGING_STATION | |||
); | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why did you add this blank line? This makes this method look different from all other in this file
@@ -158,6 +160,12 @@ public ApplicationAmbassador(AmbassadorParameter ambassadorParameter) { | |||
SimulationKernel.SimulationKernel.setCentralPerceptionComponent(centralPerceptionComponent); | |||
} | |||
|
|||
if (SimulationKernel.SimulationKernel.chargingStationIndex == null) { | |||
// use same bucketsize as TrafficLightTree (see: CPercetion.java) (bucketsize := number of direct children per tree node) | |||
ChargingStationIndex chargingStationIndex = new ChargingStationIndex(20); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe define the 20
as a constant in the ChargingStationIndex
, the way it defined right now is a magic number.
@@ -103,4 +109,10 @@ public void sendChargingStopRequest() { | |||
); | |||
sendInteractionToRti(vehicleChargingStopRequest); | |||
} | |||
|
|||
public List<ChargingStationData> getChargingStationsInArea(GeoCircle searchArea) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this return ChargingStationObjects
?
/** | ||
* The data object that stores all static and dynamic information of the charging station. | ||
*/ | ||
private ChargingStationData chargingStationData; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This field stores references to the objects contained within the ChargingStationUpdates
, which is potentially dangerous. I believe we should copy the relevant information from the ChargingStationData
and store it in these objects
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking into the ChargingStationData
, I feel like we don't require it at all as we currently are just interested in the position of the charging stations. As far as I see we don't need any info on the charging spots?!
*/ | ||
public void updateChargingStation(ChargingStationData chargingStationData) { | ||
initSearchTree(); | ||
indexedChargingStations.get(chargingStationData.getName()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is there actually anything we want to update about charging stations?
* | ||
* @param searchArea The area where the charging stations are searched | ||
*/ | ||
List<ChargingStationData> getChargingStationsInArea(GeoCircle searchArea); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why isn't this returning ChargingStationObject
s?
Description
Issue(s) related to this PR
Affected parts of the online documentation
Changes in the documentation required?
Definition of Done
Prerequisites
Required
type(scope): description
(in the style of Conventional Commits)enhancement
, orbugfix
)origin/main
has been merged into your Fork.Requested (can be enforced by maintainers)
Special notes to reviewer