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 ...@@ -115,6 +115,8 @@ public class GameLogCellRenderer extends DefaultTableCellRenderer
return GameLogFormatter.formatRefMsg(entry.getRefereeMsg()); return GameLogFormatter.formatRefMsg(entry.getRefereeMsg());
case GAME_EVENT: case GAME_EVENT:
return getGameEventMessage(entry); return getGameEventMessage(entry);
case REFEREE_GAME_EVENT:
return entry.getRefGameEvent().toString();
} }
return ""; return "";
...@@ -172,6 +174,10 @@ public class GameLogCellRenderer extends DefaultTableCellRenderer ...@@ -172,6 +174,10 @@ public class GameLogCellRenderer extends DefaultTableCellRenderer
builder.append(System.lineSeparator()); builder.append(System.lineSeparator());
builder.append(entry.getGameEvent()); builder.append(entry.getGameEvent());
break; 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(); return builder.toString();
} }
...@@ -210,6 +216,8 @@ public class GameLogCellRenderer extends DefaultTableCellRenderer ...@@ -210,6 +216,8 @@ public class GameLogCellRenderer extends DefaultTableCellRenderer
return new Color(50, 50, 50); return new Color(50, 50, 50);
case GAME_EVENT: case GAME_EVENT:
return new Color(230, 0, 0); return new Color(230, 0, 0);
case REFEREE_GAME_EVENT:
return new Color(0, 150, 225);
} }
return Color.BLACK; return Color.BLACK;
} }
......
...@@ -8,9 +8,12 @@ import java.awt.Color; ...@@ -8,9 +8,12 @@ import java.awt.Color;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import java.awt.geom.AffineTransform; import java.awt.geom.AffineTransform;
import com.sleepycat.persist.model.Persistent;
import edu.tigers.sumatra.math.vector.IVector2; import edu.tigers.sumatra.math.vector.IVector2;
@Persistent
public class DrawableArrow implements IDrawableShape public class DrawableArrow implements IDrawableShape
{ {
...@@ -20,6 +23,11 @@ public class DrawableArrow implements IDrawableShape ...@@ -20,6 +23,11 @@ public class DrawableArrow implements IDrawableShape
private int arrowSize = 25; private int arrowSize = 25;
public DrawableArrow()
{
}
public DrawableArrow(IVector2 position, IVector2 direction, Color color) public DrawableArrow(IVector2 position, IVector2 direction, Color color)
{ {
this.position = position; this.position = position;
......
...@@ -22,7 +22,7 @@ public class AutoRefConfig ...@@ -22,7 +22,7 @@ public class AutoRefConfig
@Configurable(comment = "Enable ball placement calls for the blue teams", defValue = "true") @Configurable(comment = "Enable ball placement calls for the blue teams", defValue = "true")
private static boolean ballPlacementBlueEnabled = 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; 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") @Configurable(comment = "[mm] The accuracy with which the ball needs to be placed by the human referee", defValue = "200.0")
......
...@@ -4,11 +4,14 @@ ...@@ -4,11 +4,14 @@
package edu.tigers.autoreferee; package edu.tigers.autoreferee;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.Set;
import edu.tigers.autoreferee.engine.calc.PossibleGoalCalc.PossibleGoal; import edu.tigers.autoreferee.engine.calc.PossibleGoalCalc.PossibleGoal;
import edu.tigers.autoreferee.generic.BotPosition; import edu.tigers.autoreferee.generic.BotPosition;
import edu.tigers.autoreferee.generic.TeamData;
import edu.tigers.autoreferee.generic.TimedPosition; import edu.tigers.autoreferee.generic.TimedPosition;
import edu.tigers.sumatra.drawable.ShapeMap; import edu.tigers.sumatra.drawable.ShapeMap;
import edu.tigers.sumatra.math.vector.IVector2; import edu.tigers.sumatra.math.vector.IVector2;
...@@ -27,6 +30,7 @@ public class AutoRefFrame implements IAutoRefFrame ...@@ -27,6 +30,7 @@ public class AutoRefFrame implements IAutoRefFrame
private final WorldFrameWrapper worldFrameWrapper; private final WorldFrameWrapper worldFrameWrapper;
private AutoRefFrame previousFrame; private AutoRefFrame previousFrame;
private Set<TeamData> teamInfo = new HashSet<>();
private List<BotPosition> botsLastTouchedBall = Collections.emptyList(); private List<BotPosition> botsLastTouchedBall = Collections.emptyList();
private List<BotPosition> botsTouchingBall = Collections.emptyList(); private List<BotPosition> botsTouchingBall = Collections.emptyList();
...@@ -164,6 +168,19 @@ public class AutoRefFrame implements IAutoRefFrame ...@@ -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 @Override
public ShapeMap getShapes() public ShapeMap getShapes()
{ {
......
...@@ -13,6 +13,7 @@ import edu.tigers.autoreferee.engine.calc.GameStateHistoryCalc; ...@@ -13,6 +13,7 @@ import edu.tigers.autoreferee.engine.calc.GameStateHistoryCalc;
import edu.tigers.autoreferee.engine.calc.IRefereeCalc; import edu.tigers.autoreferee.engine.calc.IRefereeCalc;
import edu.tigers.autoreferee.engine.calc.LastStopBallPositionCalc; import edu.tigers.autoreferee.engine.calc.LastStopBallPositionCalc;
import edu.tigers.autoreferee.engine.calc.PossibleGoalCalc; import edu.tigers.autoreferee.engine.calc.PossibleGoalCalc;
import edu.tigers.autoreferee.engine.calc.TeamInfoCalc;
import edu.tigers.sumatra.wp.data.WorldFrameWrapper; import edu.tigers.sumatra.wp.data.WorldFrameWrapper;
...@@ -31,6 +32,7 @@ public class AutoRefFramePreprocessor ...@@ -31,6 +32,7 @@ public class AutoRefFramePreprocessor
*/ */
public AutoRefFramePreprocessor() public AutoRefFramePreprocessor()
{ {
calculators.add(new TeamInfoCalc());
calculators.add(new BallLeftFieldCalc()); calculators.add(new BallLeftFieldCalc());
calculators.add(new BotBallContactCalc()); calculators.add(new BotBallContactCalc());
calculators.add(new GameStateHistoryCalc()); calculators.add(new GameStateHistoryCalc());
...@@ -55,7 +57,6 @@ public class AutoRefFramePreprocessor ...@@ -55,7 +57,6 @@ public class AutoRefFramePreprocessor
{ {
runCalculators(frame); runCalculators(frame);
} }
setLastFrame(frame); setLastFrame(frame);
return frame; return frame;
} }
......
...@@ -5,9 +5,11 @@ package edu.tigers.autoreferee; ...@@ -5,9 +5,11 @@ package edu.tigers.autoreferee;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.Set;
import edu.tigers.autoreferee.engine.calc.PossibleGoalCalc.PossibleGoal; import edu.tigers.autoreferee.engine.calc.PossibleGoalCalc.PossibleGoal;
import edu.tigers.autoreferee.generic.BotPosition; import edu.tigers.autoreferee.generic.BotPosition;
import edu.tigers.autoreferee.generic.TeamData;
import edu.tigers.autoreferee.generic.TimedPosition; import edu.tigers.autoreferee.generic.TimedPosition;
import edu.tigers.sumatra.drawable.ShapeMap; import edu.tigers.sumatra.drawable.ShapeMap;
import edu.tigers.sumatra.math.vector.IVector2; import edu.tigers.sumatra.math.vector.IVector2;
...@@ -48,6 +50,9 @@ public interface IAutoRefFrame ...@@ -48,6 +50,9 @@ public interface IAutoRefFrame
RefereeMsg getRefereeMsg(); RefereeMsg getRefereeMsg();
Set<TeamData> getTeamInfo();
/** /**
* Returns a list of a specified number of previous game states as well as the current one * 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; ...@@ -19,6 +19,7 @@ import edu.tigers.autoreferee.engine.log.GameLog;
import edu.tigers.autoreferee.engine.log.GameTime; import edu.tigers.autoreferee.engine.log.GameTime;
import edu.tigers.autoreferee.engine.log.IGameLog; import edu.tigers.autoreferee.engine.log.IGameLog;
import edu.tigers.sumatra.Referee.SSL_Referee.Stage; 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.GameState;
import edu.tigers.sumatra.referee.data.RefereeMsg; import edu.tigers.sumatra.referee.data.RefereeMsg;
...@@ -86,6 +87,9 @@ public abstract class AbstractAutoRefEngine implements IAutoRefEngine ...@@ -86,6 +87,9 @@ public abstract class AbstractAutoRefEngine implements IAutoRefEngine
if (curRefMsg.getCommandCounter() != lastRefMsg.getCommandCounter()) if (curRefMsg.getCommandCounter() != lastRefMsg.getCommandCounter())
{ {
gameLog.addEntry(curRefMsg); gameLog.addEntry(curRefMsg);
GameEvent lastRefEvent = frame.getPreviousFrame().getRefereeMsg().getGameEvent();
if (!lastRefEvent.equals(curRefMsg.getGameEvent()))
gameLog.addEntry(curRefMsg.getGameEvent());
} }
GameState curGameState = frame.getGameState(); 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 ...@@ -74,4 +74,15 @@ public enum EGameEvent
{ {
return gameEventType; 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; ...@@ -14,10 +14,9 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.apache.log4j.Logger;
import com.github.g3force.configurable.Configurable; import com.github.g3force.configurable.Configurable;
import edu.tigers.autoreferee.AutoRefUtil; import edu.tigers.autoreferee.AutoRefUtil;
...@@ -31,6 +30,7 @@ import edu.tigers.autoreferee.engine.events.EGameEvent; ...@@ -31,6 +30,7 @@ import edu.tigers.autoreferee.engine.events.EGameEvent;
import edu.tigers.autoreferee.engine.events.EGameEventDetectorType; import edu.tigers.autoreferee.engine.events.EGameEventDetectorType;
import edu.tigers.autoreferee.engine.events.GameEvent; import edu.tigers.autoreferee.engine.events.GameEvent;
import edu.tigers.autoreferee.engine.events.IGameEvent; import edu.tigers.autoreferee.engine.events.IGameEvent;
import edu.tigers.autoreferee.generic.TeamData;
import edu.tigers.sumatra.geometry.Geometry; import edu.tigers.sumatra.geometry.Geometry;
import edu.tigers.sumatra.ids.BotID; import edu.tigers.sumatra.ids.BotID;
import edu.tigers.sumatra.ids.ETeamColor; import edu.tigers.sumatra.ids.ETeamColor;
...@@ -47,7 +47,6 @@ import edu.tigers.sumatra.wp.data.ITrackedBot; ...@@ -47,7 +47,6 @@ import edu.tigers.sumatra.wp.data.ITrackedBot;
*/ */
public class BotCollisionDetector extends AGameEventDetector public class BotCollisionDetector extends AGameEventDetector
{ {
private static final Logger log = Logger.getLogger(BotCollisionDetector.class.getName());
private static final int PRIORITY = 1; 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") @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 ...@@ -76,7 +75,6 @@ public class BotCollisionDetector extends AGameEventDetector
private final Map<BotID, Long> lastViolators = new HashMap<>(); 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); private final Map<ETeamColor, Integer> collisionCounterPunished = new EnumMap<>(ETeamColor.class);
static static
...@@ -97,8 +95,6 @@ public class BotCollisionDetector extends AGameEventDetector ...@@ -97,8 +95,6 @@ public class BotCollisionDetector extends AGameEventDetector
EGameState.PREPARE_PENALTY, EGameState.PREPARE_PENALTY,
EGameState.PREPARE_KICKOFF, EGameState.PREPARE_KICKOFF,
EGameState.PENALTY)); EGameState.PENALTY));
collisionCounter.put(ETeamColor.YELLOW, 0);
collisionCounter.put(ETeamColor.BLUE, 0);
} }
...@@ -114,8 +110,8 @@ public class BotCollisionDetector extends AGameEventDetector ...@@ -114,8 +110,8 @@ public class BotCollisionDetector extends AGameEventDetector
{ {
if (frame.getGameState().isStoppedGame() && !stopGameOnCollisions) if (frame.getGameState().isStoppedGame() && !stopGameOnCollisions)
{ {
final List<CardPenalty> cardPenalties = newCollisionCounter().entrySet().stream() final List<CardPenalty> cardPenalties = newCollisionCounter(frame.getTeamInfo()).entrySet().stream()
.filter(e -> e.getValue() >= numCollisionsAllowed(e.getKey())) .filter(e -> e.getValue() >= numCollisionsAllowed(e.getKey(), frame.getTeamInfo()))
.map(e -> new CardPenalty(CARD_YELLOW, e.getKey())) .map(e -> new CardPenalty(CARD_YELLOW, e.getKey()))
.collect(Collectors.toList()); .collect(Collectors.toList());
...@@ -131,18 +127,24 @@ public class BotCollisionDetector extends AGameEventDetector ...@@ -131,18 +127,24 @@ public class BotCollisionDetector extends AGameEventDetector
} else if (blueTeam) } else if (blueTeam)
{ {
originatingTeam = ETeamColor.BLUE; 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) } else if (yellowTeam)
{ {
originatingTeam = ETeamColor.YELLOW; 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 } else
{ {
return Optional.empty(); return Optional.empty();
} }
cardPenalties 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(), GameEvent gameEvent = new GameEvent(EGameEvent.BOT_COLLISION, frame.getTimestamp(),
originatingTeam, null, cardPenalties); originatingTeam, null, cardPenalties);
...@@ -211,27 +213,28 @@ public class BotCollisionDetector extends AGameEventDetector ...@@ -211,27 +213,28 @@ public class BotCollisionDetector extends AGameEventDetector
kickPos = AutoRefMath.getClosestFreeKickPos(kickPos, secondaryBot.getTeamColor().opposite()); kickPos = AutoRefMath.getClosestFreeKickPos(kickPos, secondaryBot.getTeamColor().opposite());
followUp = new FollowUpAction(EActionType.FORCE_START, ETeamColor.NEUTRAL, kickPos); followUp = new FollowUpAction(EActionType.FORCE_START, ETeamColor.NEUTRAL, kickPos);
secondaryViolator = secondaryBot; secondaryViolator = secondaryBot;
collisionCounter.computeIfPresent(ETeamColor.YELLOW, (k, v) -> v + 1); frame.getTeamInfo().forEach(TeamData::botCollision);
collisionCounter.computeIfPresent(ETeamColor.BLUE, (k, v) -> v + 1);
} else } else
{ {
followUp = new FollowUpAction(EActionType.DIRECT_FREE, primaryBot.getTeamColor() followUp = new FollowUpAction(EActionType.DIRECT_FREE, primaryBot.getTeamColor()
.opposite(), kickPos); .opposite(), kickPos);
secondaryViolator = null; 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() final List<CardPenalty> cardPenalties = newCollisionCounter(frame.getTeamInfo()).entrySet().stream()
.filter(e -> e.getValue() >= numCollisionsAllowed(e.getKey())) .filter(e -> e.getValue() >= numCollisionsAllowed(e.getKey(), frame.getTeamInfo()))
.map(e -> new CardPenalty(CARD_YELLOW, e.getKey())) .map(e -> new CardPenalty(CARD_YELLOW, e.getKey()))
.collect(Collectors.toList()); .collect(Collectors.toList());
if (stopGameOnCollisions) if (stopGameOnCollisions)
{ {
cardPenalties 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 } else