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

[sync] Bugfixes and new features from Sumatra

 - UI improvements
 - more tolerance for attacker to defense area detection
 - more robust kick detection
parent d783e866
Pipeline #4479 passed with stage
in 1 minute and 48 seconds
......@@ -285,10 +285,16 @@ public class ToolBar
@Override
public void actionPerformed(final ActionEvent e)
{
for (IToolbarObserver observer : observers)
{
observer.onToggleRecord();
}
Thread t = new Thread(() -> {
btnRecSave.setEnabled(false);
for (IToolbarObserver observer : observers)
{
observer.onToggleRecord();
}
btnRecSave.setEnabled(true);
});
t.start();
}
}
......
......@@ -17,6 +17,7 @@ import org.json.simple.JSONObject;
import com.sleepycat.persist.model.Persistent;
import edu.tigers.sumatra.math.SumatraMath;
import edu.tigers.sumatra.math.circle.ICircle;
import edu.tigers.sumatra.math.line.ILine;
import edu.tigers.sumatra.math.line.Line;
import edu.tigers.sumatra.math.vector.IVector2;
......@@ -94,6 +95,16 @@ abstract class ARectangle implements IRectangle
}
@Override
public boolean isCircleInShape(final ICircle circle)
{
return SumatraMath.isBetween(circle.center().x() + circle.radius(), minX(), maxX())
&& SumatraMath.isBetween(circle.center().x() - circle.radius(), minX(), maxX())
&& SumatraMath.isBetween(circle.center().y() + circle.radius(), minY(), maxY())
&& SumatraMath.isBetween(circle.center().y() - circle.radius(), minY(), maxY());
}
@Override
public IVector2 nearestPointOutside(final IVector2 point)
{
......
......@@ -9,6 +9,7 @@ import java.util.Random;
import edu.tigers.sumatra.export.IJsonString;
import edu.tigers.sumatra.math.I2DShape;
import edu.tigers.sumatra.math.circle.ICircle;
import edu.tigers.sumatra.math.line.ILine;
import edu.tigers.sumatra.math.vector.IVector2;
......@@ -71,6 +72,8 @@ public interface IRectangle extends I2DShape, IJsonString
* @return
*/
IVector2 getRandomPointInShape(Random rnd);
boolean isCircleInShape(ICircle circle);
/**
......
......@@ -42,7 +42,7 @@ public class AttackerToDefenseAreaDistanceDetector extends APreparingGameEventDe
{
private static final int PRIORITY = 1;
private static final double INACCURACY_TOLERANCE = 5;
private static final double INACCURACY_TOLERANCE = 15;
private static final Set<EGameState> ALLOWED_PREVIOUS_STATES;
private boolean active = false;
......
......@@ -41,8 +41,8 @@ public class EarlyKickDetector implements IKickDetector
@Configurable(comment = "Ball velocity threshold [mm/s]", defValue = "1000.0")
private static double velocityThreshold = 1000.0;
@Configurable(comment = "A bot must be within this radius [mm]", defValue = "500.0")
private static double nearBotLimit = 500.0;
@Configurable(comment = "A bot must be within this radius [mm]", defValue = "150.0")
private static double nearBotLimit = 150.0;
@Configurable(comment = "Fast ball direction change threshold [deg]", defValue = "20.0")
private static double directionThreshold = 20.0;
......@@ -68,16 +68,6 @@ public class EarlyKickDetector implements IKickDetector
return null;
}
long numNearRobots = mergedRobots.stream()
.filter(b -> b.getPos().distanceTo(ball.getCamPos()) < nearBotLimit)
.count();
if (numNearRobots == 0)
{
// no kicking robot nearby :(
return null;
}
int camId = camBall.get().getCameraId();
camBallMap.putIfAbsent(camId, new LinkedList<MergedBall>());
LinkedList<MergedBall> camBallList = camBallMap.get(camId);
......@@ -103,7 +93,7 @@ public class EarlyKickDetector implements IKickDetector
return null;
}
if (!detectKick(camBallList))
if (!detectKick(camBallList, mergedRobots))
{
return null;
}
......@@ -131,12 +121,22 @@ public class EarlyKickDetector implements IKickDetector
}
private boolean detectKick(final List<MergedBall> balls)
private boolean detectKick(final List<MergedBall> balls, final List<FilteredVisionBot> mergedRobots)
{
CamBall ball0 = balls.get(0).getLatestCamBall().get();
CamBall ball1 = balls.get(1).getLatestCamBall().get();
CamBall ball2 = balls.get(2).getLatestCamBall().get();
long numNearRobots = mergedRobots.stream()
.filter(b -> b.getPos().distanceTo(ball0.getPos().getXYVector()) < nearBotLimit)
.count();
if (numNearRobots == 0)
{
// no kicking robot nearby :(
return false;
}
double t0 = (ball0.gettCapture() * 1e-9);
double t1 = (ball1.gettCapture() * 1e-9);
double t2 = (ball2.gettCapture() * 1e-9);
......
......@@ -63,5 +63,10 @@
<groupId>edu.tigers.sumatra</groupId>
<artifactId>sumatra-snapshot</artifactId>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
......@@ -8,6 +8,7 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
......@@ -23,6 +24,7 @@ import javax.swing.JOptionPane;
import javax.swing.event.MenuEvent;
import javax.swing.event.MenuListener;
import org.apache.commons.io.FileUtils;
import org.apache.log4j.Logger;
import edu.tigers.sumatra.model.SumatraModel;
......@@ -112,11 +114,28 @@ public class ReplayLoadMenu extends JMenu
JMenu subMenu = new JMenu(file.getName());
menu.add(subMenu);
for (File d : dirs)
subMenu.addMenuListener(new MenuListener()
{
addFileToMenu(d, subMenu);
}
@Override
public void menuSelected(final MenuEvent menuEvent)
{
dirs.forEach(d -> addFileToMenu(d, subMenu));
}
@Override
public void menuDeselected(final MenuEvent menuEvent)
{
// no action
}
@Override
public void menuCanceled(final MenuEvent menuEvent)
{
// no action
}
});
return;
}
}
......@@ -125,12 +144,15 @@ public class ReplayLoadMenu extends JMenu
JMenuItem rename = new JMenuItem("rename");
JMenuItem run = new JMenuItem("run");
JMenuItem delete = new JMenuItem("delete");
subsubMenu.add(run);
subsubMenu.add(rename);
subsubMenu.add(delete);
run.addActionListener(new RunActionListener(file.getAbsolutePath()));
rename.addActionListener(new RenameActionListener(file.getAbsolutePath()));
delete.addActionListener(new DeleteActionListener(file.getAbsolutePath()));
}
......@@ -243,6 +265,37 @@ public class ReplayLoadMenu extends JMenu
}
}
private class DeleteActionListener implements ActionListener
{
final String filename;
public DeleteActionListener(final String absolutePath)
{
this.filename = absolutePath;
}
@Override
public void actionPerformed(final ActionEvent e)
{
if (JOptionPane.showConfirmDialog(null, "Do you want to delete '" + filename + "'?", "Confirm deletion",
JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION)
{
log.info("Deleting '" + filename + "'...");
try
{
FileUtils.deleteDirectory(new File(filename));
} catch (IOException exception)
{
log.error("Replay deletion not successful!", exception);
}
}
}
}
private class SetDefaultPathListener implements ActionListener
{
......
......@@ -21,20 +21,28 @@ public enum EVisualizerOptions implements IShapeLayer
/** */
RESET_FIELD("Visualizer", "reset field"),
/** */
DARK("Visualizer", "dark mode"),;
DARK("Visualizer", "dark mode", false);
private final String name;
private final String category;
private final boolean isVisibleByDefault;
EVisualizerOptions(final String category, final String name)
{
this(category, name, true);
}
/**
* @param name this name will be shown to the user
*/
EVisualizerOptions(final String category, final String name)
EVisualizerOptions(final String category, final String name, final boolean isVisibleByDefault)
{
this.name = name;
this.category = category;
this.isVisibleByDefault = isVisibleByDefault;
}
......@@ -65,6 +73,6 @@ public enum EVisualizerOptions implements IShapeLayer
@Override
public boolean isVisibleByDefault()
{
return true;
return isVisibleByDefault;
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment