Skip to content

Commit

Permalink
Docs: Added comments
Browse files Browse the repository at this point in the history
  • Loading branch information
Topvennie committed Apr 20, 2024
1 parent 7ddd89b commit d7953c3
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.util.LinkedList;

// LinkedList with a maximum length
public class CircularQueue<T> extends LinkedList<T> {

private final int maxSize;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public DetectionList(int interval, List<Station> stations) {
this.newestDetection = new Timestamp(0);
}

// Returns True if it's a new station
// Returns True if the added detection results in a new station
@Override
public boolean add(Detection e) {
super.add(e);
Expand Down
38 changes: 21 additions & 17 deletions src/main/java/telraam/logic/positioner/nostradamus/Nostradamus.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,21 @@

public class Nostradamus implements Positioner {
private static final Logger logger = Logger.getLogger(Nostradamus.class.getName());
private final int INTERVAL_CALCULATE_MS = 500; // How often to handle new detections
private final int INTERVAL_FETCH_MS = 60000; // Interval between fetching all stations, teams, ...
private final int INTERVAL_CALCULATE_MS = 500; // How often to handle new detections (in milliseconds)
private final int INTERVAL_FETCH_MS = 60000; // Interval between fetching baton switchovers (in milliseconds)
private final int INTERVAL_DETECTIONS_MS = 3000; // Amount of milliseconds to group detections by
private final int AVERAGE_AMOUNT = 10; // Calculate the average running speed the last x intervals
private final double AVERAGE_SPRINTING_SPEED_M_MS = 0.00684; // Average sprinting speed m / ms
private final int MIN_RSSI = -84;
private final int FINISH_OFFSET = 0;
private final int MAX_NO_DATA_MS = 30000;
private final int MAX_NO_DATA_MS = 30000; // Send a stationary position after receiving no station update for x amount of milliseconds
private final int AVERAGE_AMOUNT = 10; // Calculate the median running speed of the last x intervals
private final double AVERAGE_SPRINTING_SPEED_M_MS = 0.00684; // Average sprinting speed meters / milliseconds
private final int MIN_RSSI = -84; // Minimum rssi strength for a detection
private final int FINISH_OFFSET_M = 0; // Distance between the last station and the finish in meters
private final Jdbi jdbi;
private final List<Detection> newDetections; // Contains not yet handled detections
private final Lock detectionLock;
private final Lock dataLock;
private Map<Integer, Integer> batonToTeam; // Baton ID to Team ID
private Map<Integer, TeamData> teamData; // All team data
private final Map<Integer, TeamData> teamData; // All team data
private final PositionSender positionSender;
private final Lock detectionLock;
private final Lock dataLock;

public Nostradamus(Jdbi jdbi) {
this.jdbi = jdbi;
Expand All @@ -44,25 +44,27 @@ public Nostradamus(Jdbi jdbi) {

// Will be filled by fetch
this.batonToTeam = new HashMap<>();
setTeamData();
this.teamData = getTeamData();

this.positionSender = new PositionSender();

new Thread(this::fetch).start();
new Thread(this::calculatePosition).start();
}

private void setTeamData() {
// Initiate the team data map
private Map<Integer, TeamData> getTeamData() {
List<Station> stations = jdbi.onDemand(StationDAO.class).getAll();
stations.sort(Comparator.comparing(Station::getDistanceFromStart));
List<Team> teams = jdbi.onDemand(TeamDAO.class).getAll();

teamData = teams.stream().collect(Collectors.toMap(
return teams.stream().collect(Collectors.toMap(
Team::getId,
team -> new TeamData(team.getId(), INTERVAL_DETECTIONS_MS, stations, AVERAGE_AMOUNT, AVERAGE_SPRINTING_SPEED_M_MS, FINISH_OFFSET)
team -> new TeamData(team.getId(), INTERVAL_DETECTIONS_MS, stations, AVERAGE_AMOUNT, AVERAGE_SPRINTING_SPEED_M_MS, FINISH_OFFSET_M)
));
}

// Fetch all baton switchovers and replace the current one if there are any changes
private void fetch() {
List<BatonSwitchover> switchovers = jdbi.onDemand(BatonSwitchoverDAO.class).getAll();

Expand All @@ -80,19 +82,20 @@ private void fetch() {
dataLock.unlock();
}

// zzzzzzzz
// Sleep tight
try {
Thread.sleep(INTERVAL_FETCH_MS);
} catch (InterruptedException e) {
logger.severe(e.getMessage());
}
}

// handle all new detections and update positions accordingly
private void calculatePosition() {
Set<Integer> changedTeams = new HashSet<>(); // List of teams that have changed station
while (true) {
dataLock.lock();
changedTeams.clear();
dataLock.lock();
detectionLock.lock();
for (Detection detection: newDetections) {
if (batonToTeam.containsKey(detection.getBatonId())) {
Expand All @@ -118,6 +121,7 @@ private void calculatePosition() {
);
}

// Send a stationary position if no new station data was received recently
long now = System.currentTimeMillis();
for (Map.Entry<Integer, TeamData> entry: teamData.entrySet()) {
if (now - entry.getValue().getPreviousStationArrival() > MAX_NO_DATA_MS) {
Expand All @@ -130,7 +134,7 @@ private void calculatePosition() {
}
}

// zzzzzzzz
// Goodnight
try {
Thread.sleep(INTERVAL_CALCULATE_MS);
} catch (InterruptedException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.util.ArrayList;
import java.util.List;

// Record containing all data necessary for TeamData
public record StationData(
Station station, // The station
Station nextStation, // The next station
Expand Down
14 changes: 7 additions & 7 deletions src/main/java/telraam/logic/positioner/nostradamus/TeamData.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@
public class TeamData {
private final DetectionList detections; // List with all relevant detections
private final Map<Integer, StationData> stations; // Station list
@Getter
private long previousStationArrival; // Arrival time of previous station. Used to calculate the average times
private StationData currentStation; // Current station location
private StationData previousStation; // Previous station location
@Getter
private long previousStationArrival; // Arrival time of previous station. Used to calculate the average times
private final int totalDistance; // Total distance of the track
private final float maxDeviance; // Maximum deviance the animation can have from the reality
@Getter
private final Position position; // Data to send to the websocket
private final float maxDeviance; // Maximum deviance the animation can have from the reality


public TeamData(int teamId, int interval, List<Station> stations, int averageAmount, double sprintingSpeed, int finishOffset) {
Expand All @@ -33,7 +33,7 @@ public TeamData(int teamId, int interval, List<Station> stations, int averageAmo
totalDistance
)
));
// Pre-populate with some data
// Pre-populate with some default values
this.stations.forEach((stationId, stationData) -> stationData.times().add(
(long) (((stationData.nextStation().getDistanceFromStart() - stationData.station().getDistanceFromStart() + totalDistance) % totalDistance) / sprintingSpeed)
));
Expand Down Expand Up @@ -88,7 +88,7 @@ public void updatePosition() {
double theoreticalProgress = normalize(position.getProgress() + (position.getSpeed() * milliSecondsSince));

// Arrive at next station at timestamp y and progress z
double median = getMedian(currentStation.times());
double median = getMedian();
double nextStationArrival = currentTime + median;
double goalProgress = currentStation.nextProgress();

Expand All @@ -109,8 +109,8 @@ public void updatePosition() {
}

// Get the medium of the average times
private long getMedian(List<Long> times) {
List<Long> sortedList = new ArrayList<>(times);
private long getMedian() {
List<Long> sortedList = new ArrayList<>(currentStation.times());
Collections.sort(sortedList);

int size = sortedList.size();
Expand Down

0 comments on commit d7953c3

Please sign in to comment.