Commit a415bc0b authored by Nicolai Ommer's avatar Nicolai Ommer
Browse files

[sync] Bugfixing + UI improvements

 - Add game event from refbox to game log
 - count collisions and stop speed correctly, when colors change
parent d46c0f85
Pipeline #5044 passed with stage
in 59 seconds
......@@ -115,6 +115,8 @@ public class GameLogCellRenderer extends DefaultTableCellRenderer
return GameLogFormatter.formatRefMsg(entry.getRefereeMsg());
case GAME_EVENT:
return getGameEventMessage(entry);
case REFEREE_GAME_EVENT:
return entry.getRefGameEvent().toString();
}
return "";
......@@ -172,6 +174,10 @@ public class GameLogCellRenderer extends DefaultTableCellRenderer
builder.append(System.lineSeparator());
builder.append(entry.getGameEvent());
break;
case REFEREE_GAME_EVENT:
builder.append("The Referee send the following GameEvent message: ");
builder.append(System.lineSeparator());
builder.append(entry.getRefGameEvent().toString());
}
return builder.toString();
}
......@@ -210,6 +216,8 @@ public class GameLogCellRenderer extends DefaultTableCellRenderer
return new Color(50, 50, 50);
case GAME_EVENT:
return new Color(230, 0, 0);
case REFEREE_GAME_EVENT:
return new Color(0, 150, 225);
}
return Color.BLACK;
}
......
......@@ -8,9 +8,12 @@ import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import com.sleepycat.persist.model.Persistent;
import edu.tigers.sumatra.math.vector.IVector2;
@Persistent
public class DrawableArrow implements IDrawableShape
{
......@@ -20,6 +23,11 @@ public class DrawableArrow implements IDrawableShape
private int arrowSize = 25;
public DrawableArrow()
{
}
public DrawableArrow(IVector2 position, IVector2 direction, Color color)
{
this.position = position;
......
......@@ -22,7 +22,7 @@ public class AutoRefConfig
@Configurable(comment = "Enable ball placement calls for the blue teams", defValue = "true")
private static boolean ballPlacementBlueEnabled = true;
@Configurable(comment = "Enable ball placement calls for the blue teams", defValue = "true")
@Configurable(comment = "Enable ball placement calls for the yellow teams", defValue = "true")
private static boolean ballPlacementYellowEnabled = true;
@Configurable(comment = "[mm] The accuracy with which the ball needs to be placed by the human referee", defValue = "200.0")
......
......@@ -4,11 +4,14 @@
package edu.tigers.autoreferee;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import edu.tigers.autoreferee.engine.calc.PossibleGoalCalc.PossibleGoal;
import edu.tigers.autoreferee.generic.BotPosition;
import edu.tigers.autoreferee.generic.TeamData;
import edu.tigers.autoreferee.generic.TimedPosition;
import edu.tigers.sumatra.drawable.ShapeMap;
import edu.tigers.sumatra.math.vector.IVector2;
......@@ -27,6 +30,7 @@ public class AutoRefFrame implements IAutoRefFrame
private final WorldFrameWrapper worldFrameWrapper;
private AutoRefFrame previousFrame;
private Set<TeamData> teamInfo = new HashSet<>();
private List<BotPosition> botsLastTouchedBall = Collections.emptyList();
private List<BotPosition> botsTouchingBall = Collections.emptyList();
......@@ -164,6 +168,19 @@ public class AutoRefFrame implements IAutoRefFrame
}
@Override
public Set<TeamData> getTeamInfo()
{
return teamInfo;
}
public void setTeamInfo(Set<TeamData> teamInfo)
{
this.teamInfo.addAll(teamInfo);
}
@Override
public ShapeMap getShapes()
{
......
......@@ -13,6 +13,7 @@ import edu.tigers.autoreferee.engine.calc.GameStateHistoryCalc;
import edu.tigers.autoreferee.engine.calc.IRefereeCalc;
import edu.tigers.autoreferee.engine.calc.LastStopBallPositionCalc;
import edu.tigers.autoreferee.engine.calc.PossibleGoalCalc;
import edu.tigers.autoreferee.engine.calc.TeamInfoCalc;
import edu.tigers.sumatra.wp.data.WorldFrameWrapper;
......@@ -31,6 +32,7 @@ public class AutoRefFramePreprocessor
*/
public AutoRefFramePreprocessor()
{
calculators.add(new TeamInfoCalc());
calculators.add(new BallLeftFieldCalc());
calculators.add(new BotBallContactCalc());
calculators.add(new GameStateHistoryCalc());
......@@ -55,7 +57,6 @@ public class AutoRefFramePreprocessor
{
runCalculators(frame);
}
setLastFrame(frame);
return frame;
}
......
......@@ -5,9 +5,11 @@ package edu.tigers.autoreferee;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import edu.tigers.autoreferee.engine.calc.PossibleGoalCalc.PossibleGoal;
import edu.tigers.autoreferee.generic.BotPosition;
import edu.tigers.autoreferee.generic.TeamData;
import edu.tigers.autoreferee.generic.TimedPosition;
import edu.tigers.sumatra.drawable.ShapeMap;
import edu.tigers.sumatra.math.vector.IVector2;
......@@ -48,6 +50,9 @@ public interface IAutoRefFrame
RefereeMsg getRefereeMsg();
Set<TeamData> getTeamInfo();
/**
* Returns a list of a specified number of previous game states as well as the current one
*
......
......@@ -19,6 +19,7 @@ import edu.tigers.autoreferee.engine.log.GameLog;
import edu.tigers.autoreferee.engine.log.GameTime;
import edu.tigers.autoreferee.engine.log.IGameLog;
import edu.tigers.sumatra.Referee.SSL_Referee.Stage;
import edu.tigers.sumatra.referee.data.GameEvent;
import edu.tigers.sumatra.referee.data.GameState;
import edu.tigers.sumatra.referee.data.RefereeMsg;
......@@ -86,6 +87,9 @@ public abstract class AbstractAutoRefEngine implements IAutoRefEngine
if (curRefMsg.getCommandCounter() != lastRefMsg.getCommandCounter())
{
gameLog.addEntry(curRefMsg);
GameEvent lastRefEvent = frame.getPreviousFrame().getRefereeMsg().getGameEvent();
if (!lastRefEvent.equals(curRefMsg.getGameEvent()))
gameLog.addEntry(curRefMsg.getGameEvent());
}
GameState curGameState = frame.getGameState();
......
/*
* Copyright (c) 2009 - 2018, DHBW Mannheim - TIGERs Mannheim
*/
package edu.tigers.autoreferee.engine.calc;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import edu.tigers.autoreferee.AutoRefFrame;
import edu.tigers.autoreferee.generic.TeamData;
import edu.tigers.sumatra.ids.ETeamColor;
import edu.tigers.sumatra.referee.data.TeamInfo;
/**
* @author Ulrike Leipscher <ulrike.leipscher@dlr.de>.
*/
public class TeamInfoCalc implements IRefereeCalc
{
@Override
public void process(final AutoRefFrame frame)
{
Set<TeamData> lastTeamInfo = frame.getPreviousFrame().getTeamInfo();
if (lastTeamInfo.isEmpty())
{
Set<TeamData> teams = new HashSet<>();
teams.add(new TeamData(frame.getRefereeMsg().getTeamInfoYellow(), ETeamColor.YELLOW));
teams.add(new TeamData(frame.getRefereeMsg().getTeamInfoBlue(), ETeamColor.BLUE));
frame.setTeamInfo(teams);
return;
}
boolean yellowSet = false;
int yellowID = 0;
boolean blueSet = false;
int blueID = 0;
TeamInfo yellowTeam = frame.getRefereeMsg().getTeamInfoYellow();
TeamInfo blueTeam = frame.getRefereeMsg().getTeamInfoBlue();
Set<TeamData> currentTeamInfo = new HashSet<>();
if (!"".equals(yellowTeam.getName()))
{
List<TeamData> data = lastTeamInfo.stream()
.filter(teamData -> teamData.getTeam().equals(yellowTeam.getName())).collect(Collectors.toList());
if (data.size() == 1)
{
currentTeamInfo.add(updateTeamData(data.get(0), yellowTeam, ETeamColor.YELLOW));
yellowSet = true;
yellowID = data.get(0).getId();
}
}
if (!"".equals(blueTeam.getName()))
{
List<TeamData> data = lastTeamInfo.stream()
.filter(teamData -> teamData.getTeam().equals(blueTeam.getName())).collect(Collectors.toList());
if (data.size() == 1)
{
currentTeamInfo.add(updateTeamData(data.get(0), blueTeam, ETeamColor.BLUE));
blueSet = true;
blueID = data.get(0).getId();
}
}
if (!yellowSet)
{
if (blueSet)
{
final int finalBlueID = blueID;
List<TeamData> yellowData = lastTeamInfo.stream()
.filter(teamData -> teamData.getId() != finalBlueID)
.collect(Collectors.toList());
currentTeamInfo.add(updateTeamData(yellowData.get(0), yellowTeam, ETeamColor.YELLOW));
yellowID = yellowData.get(0).getId();
} else
{
List<TeamData> yellowData = lastTeamInfo.stream()
.filter(teamData -> teamData.getTeamColor() == ETeamColor.YELLOW)
.collect(Collectors.toList());
currentTeamInfo.add(updateTeamData(yellowData.get(0), yellowTeam, ETeamColor.YELLOW));
yellowID = yellowData.get(0).getId();
}
}
if (!blueSet)
{
final int finalYellowID = yellowID;
List<TeamData> blueData = lastTeamInfo.stream()
.filter(teamData -> teamData.getId() != finalYellowID)
.collect(Collectors.toList());
currentTeamInfo.add(updateTeamData(blueData.get(0), blueTeam, ETeamColor.BLUE));
}
frame.setTeamInfo(currentTeamInfo);
}
private TeamData updateTeamData(TeamData teamData, TeamInfo info, ETeamColor color)
{
teamData.setTeam(info.getName());
teamData.setTeamColor(color);
return teamData;
}
}
......@@ -74,4 +74,15 @@ public enum EGameEvent
{
return gameEventType;
}
public static EGameEvent getForGameEventType(GameEventType t)
{
for(EGameEvent event : EGameEvent.values())
{
if(event.getGameEventType() == t)
return event;
}
return null;
}
}
......@@ -14,10 +14,9 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.log4j.Logger;
import com.github.g3force.configurable.Configurable;
import edu.tigers.autoreferee.AutoRefUtil;
......@@ -31,6 +30,7 @@ import edu.tigers.autoreferee.engine.events.EGameEvent;
import edu.tigers.autoreferee.engine.events.EGameEventDetectorType;
import edu.tigers.autoreferee.engine.events.GameEvent;
import edu.tigers.autoreferee.engine.events.IGameEvent;
import edu.tigers.autoreferee.generic.TeamData;
import edu.tigers.sumatra.geometry.Geometry;
import edu.tigers.sumatra.ids.BotID;
import edu.tigers.sumatra.ids.ETeamColor;
......@@ -47,7 +47,6 @@ import edu.tigers.sumatra.wp.data.ITrackedBot;
*/
public class BotCollisionDetector extends AGameEventDetector
{
private static final Logger log = Logger.getLogger(BotCollisionDetector.class.getName());
private static final int PRIORITY = 1;
@Configurable(comment = "[m/s] The velocity threshold above with a bot contact is considered a crash", defValue = "1.5")
......@@ -76,7 +75,6 @@ public class BotCollisionDetector extends AGameEventDetector
private final Map<BotID, Long> lastViolators = new HashMap<>();
private final Map<ETeamColor, Integer> collisionCounter = new EnumMap<>(ETeamColor.class);
private final Map<ETeamColor, Integer> collisionCounterPunished = new EnumMap<>(ETeamColor.class);
static
......@@ -97,8 +95,6 @@ public class BotCollisionDetector extends AGameEventDetector
EGameState.PREPARE_PENALTY,
EGameState.PREPARE_KICKOFF,
EGameState.PENALTY));
collisionCounter.put(ETeamColor.YELLOW, 0);
collisionCounter.put(ETeamColor.BLUE, 0);
}
......@@ -114,8 +110,8 @@ public class BotCollisionDetector extends AGameEventDetector
{
if (frame.getGameState().isStoppedGame() && !stopGameOnCollisions)
{
final List<CardPenalty> cardPenalties = newCollisionCounter().entrySet().stream()
.filter(e -> e.getValue() >= numCollisionsAllowed(e.getKey()))
final List<CardPenalty> cardPenalties = newCollisionCounter(frame.getTeamInfo()).entrySet().stream()
.filter(e -> e.getValue() >= numCollisionsAllowed(e.getKey(), frame.getTeamInfo()))
.map(e -> new CardPenalty(CARD_YELLOW, e.getKey()))
.collect(Collectors.toList());
......@@ -131,18 +127,24 @@ public class BotCollisionDetector extends AGameEventDetector
} else if (blueTeam)
{
originatingTeam = ETeamColor.BLUE;
message = String.format("Yellow card for %d. robot collision", collisionCounter.get(originatingTeam));
int collisions = frame.getTeamInfo().stream().filter(teamData -> teamData.getTeamColor() == originatingTeam)
.mapToInt(TeamData::getBotCollisions).findFirst().orElse(0);
message = String.format("Yellow card for %d. robot collision", collisions);
} else if (yellowTeam)
{
originatingTeam = ETeamColor.YELLOW;
message = String.format("Yellow card for %d. robot collision", collisionCounter.get(originatingTeam));
int collisions = frame.getTeamInfo().stream().filter(teamData -> teamData.getTeamColor() == originatingTeam)
.mapToInt(TeamData::getBotCollisions).findFirst().orElse(0);
message = String.format("Yellow card for %d. robot collision", collisions);
} else
{
return Optional.empty();
}
cardPenalties
.forEach(c -> collisionCounterPunished.put(c.getCardTeam(), collisionCounter.get(c.getCardTeam())));
.forEach(c -> collisionCounterPunished.put(c.getCardTeam(),
frame.getTeamInfo().stream().filter(teamData -> teamData.getTeamColor() == c.getCardTeam())
.mapToInt(TeamData::getBotCollisions).findFirst().orElse(0)));
GameEvent gameEvent = new GameEvent(EGameEvent.BOT_COLLISION, frame.getTimestamp(),
originatingTeam, null, cardPenalties);
......@@ -211,27 +213,28 @@ public class BotCollisionDetector extends AGameEventDetector
kickPos = AutoRefMath.getClosestFreeKickPos(kickPos, secondaryBot.getTeamColor().opposite());
followUp = new FollowUpAction(EActionType.FORCE_START, ETeamColor.NEUTRAL, kickPos);
secondaryViolator = secondaryBot;
collisionCounter.computeIfPresent(ETeamColor.YELLOW, (k, v) -> v + 1);
collisionCounter.computeIfPresent(ETeamColor.BLUE, (k, v) -> v + 1);
frame.getTeamInfo().forEach(TeamData::botCollision);
} else
{
followUp = new FollowUpAction(EActionType.DIRECT_FREE, primaryBot.getTeamColor()
.opposite(), kickPos);
secondaryViolator = null;
collisionCounter.computeIfPresent(primaryBot.getTeamColor(), (k, v) -> v + 1);
frame.getTeamInfo().stream().filter(data -> data.getTeamColor() == primaryBot.getTeamColor())
.forEach(TeamData::botCollision);
}
log.info("New bot collision counter: " + collisionCounter);
final List<CardPenalty> cardPenalties = newCollisionCounter().entrySet().stream()
.filter(e -> e.getValue() >= numCollisionsAllowed(e.getKey()))
final List<CardPenalty> cardPenalties = newCollisionCounter(frame.getTeamInfo()).entrySet().stream()
.filter(e -> e.getValue() >= numCollisionsAllowed(e.getKey(), frame.getTeamInfo()))
.map(e -> new CardPenalty(CARD_YELLOW, e.getKey()))
.collect(Collectors.toList());
if (stopGameOnCollisions)
{
cardPenalties
.forEach(c -> collisionCounterPunished.put(c.getCardTeam(), collisionCounter.get(c.getCardTeam())));
.forEach(c -> collisionCounterPunished.put(c.getCardTeam(),
frame.getTeamInfo().stream().filter(teamData -> teamData.getTeamColor() == c.getCardTeam())
.mapToInt(TeamData::getBotCollisions).findFirst().orElse(0)));
} else
{
followUp = null;
......@@ -250,12 +253,14 @@ public class BotCollisionDetector extends AGameEventDetector
{
violation.setCustomMessage(String.format("%s collided into %s @ %.2f m/s (Δv %.2f m/s) (%d. time)",
primaryBot.getSaveableString(), secondaryBot.getSaveableString(), crashVel, velDiff,
collisionCounter.getOrDefault(primaryBot.getTeamColor(), 0)));
frame.getTeamInfo().stream().filter(teamData -> teamData.getTeamColor() == primaryBot.getTeamColor())
.mapToInt(TeamData::getBotCollisions).findFirst().orElse(0)));
} else
{
violation.setCustomMessage(String.format("Both %s and %s collided @ %.2f m/s (Δv= %.2f m/s) (%d. time)",
primaryBot.getSaveableString(), secondaryBot.getSaveableString(), crashVel, velDiff,
collisionCounter.getOrDefault(primaryBot.getTeamColor(), 0)));
frame.getTeamInfo().stream().filter(teamData -> teamData.getTeamColor() == primaryBot.getTeamColor())
.mapToInt(TeamData::getBotCollisions).findFirst().orElse(0)));
}
return Optional.of(violation);
}
......@@ -263,21 +268,22 @@ public class BotCollisionDetector extends AGameEventDetector
}
private Map<ETeamColor, Integer> newCollisionCounter()
private Map<ETeamColor, Integer> newCollisionCounter(Set<TeamData> data)
{
Map<ETeamColor, Integer> newCollisionsCounter = new EnumMap<>(ETeamColor.class);
for (Map.Entry<ETeamColor, Integer> entry : collisionCounter.entrySet())
for (TeamData d : data)
{
newCollisionsCounter.put(entry.getKey(),
entry.getValue() - collisionCounterPunished.getOrDefault(entry.getKey(), 0));
newCollisionsCounter.put(d.getTeamColor(),
d.getBotCollisions() - collisionCounterPunished.getOrDefault(d.getTeamColor(), 0));
}
return newCollisionsCounter;
}
private int numCollisionsAllowed(final ETeamColor teamColor)
private int numCollisionsAllowed(final ETeamColor teamColor, Set<TeamData> data)
{
if (collisionCounter.get(teamColor) > numCollisionForFirstYellowCard)
if (data.stream().filter(teamData -> teamData.getTeamColor() == teamColor)
.mapToInt(TeamData::getBotCollisions).findFirst().orElse(0) > numCollisionForFirstYellowCard)
{
return numCollisionPerYellowCard;
}
......
......@@ -30,6 +30,7 @@ import edu.tigers.autoreferee.engine.events.EGameEvent;
import edu.tigers.autoreferee.engine.events.EGameEventDetectorType;
import edu.tigers.autoreferee.engine.events.IGameEvent;
import edu.tigers.autoreferee.engine.events.SpeedViolation;
import edu.tigers.autoreferee.generic.TeamData;
import edu.tigers.sumatra.ids.BotID;
import edu.tigers.sumatra.ids.ETeamColor;
import edu.tigers.sumatra.ids.IBotIDMap;
......@@ -54,7 +55,7 @@ public class BotStopSpeedDetector extends APreparingGameEventDetector
@Configurable(comment = "Number of infringements allowed, until a yellow card is issued", defValue = "3")
private static int numInfringementsPerYellowCard = 3;
static
{
AGameEventDetector.registerClass(BotStopSpeedDetector.class);
......@@ -63,7 +64,6 @@ public class BotStopSpeedDetector extends APreparingGameEventDetector
private long entryTime = 0;
private Map<BotID, Long> currentViolators = new HashMap<>();
private Set<BotID> lastViolators = new HashSet<>();
private Map<ETeamColor, Integer> counter = new EnumMap<>(ETeamColor.class);
private Map<ETeamColor, Boolean> infringementRecordedThisStopPhase = new EnumMap<>(ETeamColor.class);
......@@ -73,8 +73,6 @@ public class BotStopSpeedDetector extends APreparingGameEventDetector
public BotStopSpeedDetector()
{
super(EGameEventDetectorType.BOT_STOP_SPEED, EGameState.STOP);
counter.put(ETeamColor.YELLOW, 0);
counter.put(ETeamColor.BLUE, 0);
}
......@@ -144,21 +142,27 @@ public class BotStopSpeedDetector extends APreparingGameEventDetector
if (!infringementRecordedThisStopPhase.getOrDefault(violator.getTeamColor(), true))
{
counter.computeIfPresent(violator.getTeamColor(), (k, v) -> v + 1);
frame.getTeamInfo().stream().filter(data -> data.getTeamColor() == violator.getTeamColor())
.forEach(TeamData::botStopSpeeding);
infringementRecordedThisStopPhase.put(violator.getTeamColor(), true);
log.info("New bot stop speed infringement counter: " + counter);
log.info("New bot stop speed infringement counter: "
+ frame.getTeamInfo().stream().filter(data -> data.getTeamColor() == violator.getTeamColor())
.mapToInt(TeamData::getBotStopSpeeding).findFirst().orElse(0));
}
final List<CardPenalty> cardPenalties = counter.entrySet().stream()
.filter(e -> e.getValue() >= numInfringementsPerYellowCard)
.map(e -> new CardPenalty(CARD_YELLOW, e.getKey()))
final List<CardPenalty> cardPenalties = frame.getTeamInfo().stream()
.filter(e -> e.getBotStopSpeeding() >= numInfringementsPerYellowCard)
.map(e -> new CardPenalty(CARD_YELLOW, e.getTeamColor()))
.collect(Collectors.toList());
SpeedViolation violation = new SpeedViolation(EGameEvent.ROBOT_STOP_SPEED, frame.getTimestamp(), violator,
null, bot.getVel().getLength(), cardPenalties, counter.get(violator.getTeamColor()));
null, bot.getVel().getLength(), cardPenalties,
frame.getTeamInfo().stream().filter(data -> data.getTeamColor() == violator.getTeamColor())
.mapToInt(TeamData::getBotStopSpeeding).findFirst().orElse(0));
violation.setStopGame(false);
counter.entrySet().forEach(e -> e.setValue(e.getValue() % numInfringementsPerYellowCard)); // reset counter
frame.getTeamInfo().forEach(e -> e.setBotStopSpeeding(e.getBotStopSpeeding() % numInfringementsPerYellowCard)); // reset
// counter
return Optional.of(violation);
}
......
......@@ -4,8 +4,6 @@
package edu.tigers.autoreferee.engine.events.impl;
import java.util.EnumMap;
import java.util.Map;
import java.util.Optional;
import com.github.g3force.configurable.Configurable;
......@@ -17,6 +15,7 @@ import edu.tigers.autoreferee.engine.events.EGameEvent;
import edu.tigers.autoreferee.engine.events.EGameEventDetectorType;
import edu.tigers.autoreferee.engine.events.GameEvent;
import edu.tigers.autoreferee.engine.events.IGameEvent;
import edu.tigers.autoreferee.generic.TeamData;
import edu.tigers.sumatra.ids.ETeamColor;
import edu.tigers.sumatra.referee.data.EGameState;
......@@ -32,14 +31,11 @@ public class MultipleYellowCardsDetector extends AGameEventDetector
private static int numberOfYellowCards = 3;
private boolean penaltyGivenInThisStopPhase = false;
private final Map<ETeamColor, Integer> cardOffsets = new EnumMap<>(ETeamColor.class);
public MultipleYellowCardsDetector()
{
super(EGameEventDetectorType.MULTIPLE_YELLOW_CARDS, EGameState.STOP);