Skip to content

Commit

Permalink
Initial version of autoRef CI implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
g3force committed May 15, 2022
1 parent 0018f55 commit 380962e
Show file tree
Hide file tree
Showing 47 changed files with 637 additions and 85 deletions.
7 changes: 5 additions & 2 deletions .idea/runConfigurations/AutoReferee.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ dependencies {

implementation project(':moduli-record')
implementation project(':moduli-autoreferee')
runtimeOnly project(':moduli-autoreferee-ci')
runtimeOnly project(':moduli-wp')
runtimeOnly project(':moduli-referee')

Expand Down
68 changes: 68 additions & 0 deletions config/moduli/moduli-ci.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?xml version="1.0" encoding="UTF-8" ?>
<centralSoftware>

<!--
This configuration is copied to the AutoReferee when synchronizing source code. It must not be removed or renamed!
-->

<globalConfiguration>
<environment>ROBOCUP</environment>
<geometry>DIV_A</geometry>
</globalConfiguration>


<module id="edu.tigers.sumatra.cam.ACam">
<implementation>edu.tigers.autoreferee.ci.AutoRefereeCiCamModule</implementation>

<properties>
<port>10013</port>
</properties>
</module>


<module id="edu.tigers.sumatra.geometry.GeometryUpdater">
<dependency>edu.tigers.sumatra.cam.ACam</dependency>
</module>


<module id="edu.tigers.sumatra.vision.AVisionFilter">
<implementation>edu.tigers.sumatra.vision.VisionFilterImpl</implementation>

<dependency>edu.tigers.sumatra.referee.AReferee</dependency>
<dependency>edu.tigers.sumatra.cam.ACam</dependency>
</module>


<module id="edu.tigers.sumatra.wp.AWorldPredictor">
<implementation>edu.tigers.sumatra.wp.WorldInfoCollector</implementation>

<dependency>edu.tigers.sumatra.referee.AReferee</dependency>
<dependency>edu.tigers.sumatra.vision.AVisionFilter</dependency>
<dependency>edu.tigers.sumatra.persistence.RecordManager</dependency>
<dependency>edu.tigers.sumatra.cam.ACam</dependency>
</module>


<module id="edu.tigers.sumatra.referee.AReferee">
<implementation>edu.tigers.sumatra.referee.Referee</implementation>

<properties>
<source>INTERNAL_FORWARDER</source>
</properties>
</module>


<module id="edu.tigers.autoreferee.module.AutoRefModule">
<properties>
<gameControllerPort>10007</gameControllerPort>
</properties>

<dependency>edu.tigers.sumatra.wp.AWorldPredictor</dependency>
</module>


<module id="edu.tigers.sumatra.persistence.RecordManager">
<implementation>edu.tigers.autoreferee.AutoRefRecordManager</implementation>
</module>

</centralSoftware>
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ public class BallState implements IMirrorable<BallState>
/**
* The spin of the ball in [rad/s], positive spin corresponds to positive linear velocity
*/
@NonNull
IVector2 spin;


Expand Down
27 changes: 27 additions & 0 deletions modules/moduli-autoreferee-ci/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright (c) 2009 - 2021, DHBW Mannheim - TIGERs Mannheim
*/

plugins {
id 'sumatra.java'
id 'java-library'
id 'sumatra.protobuf'
}

dependencies {
implementation project(':common')
implementation project(':common-math')
implementation project(':sumatra-model')
implementation project(':moduli-wp')
implementation project(':moduli-vision')
implementation project(':moduli-geometry')
implementation project(':moduli-referee')
implementation project(':moduli-cam')

implementation 'com.github.TIGERs-Mannheim:moduli:4.1'

implementation 'org.apache.logging.log4j:log4j-api:2.17.1'
implementation 'commons-configuration:commons-configuration:1.10'

implementation 'com.google.protobuf:protobuf-java:3.19.4'
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/*
* Copyright (c) 2009 - 2022, DHBW Mannheim - TIGERs Mannheim
*/

package edu.tigers.autoreferee.ci;

import edu.tigers.moduli.exceptions.StartModuleException;
import edu.tigers.sumatra.cam.ACam;
import edu.tigers.sumatra.cam.SSLVisionCamGeometryTranslator;
import edu.tigers.sumatra.cam.data.CamGeometry;
import edu.tigers.sumatra.cam.proto.SslVisionDetection;
import edu.tigers.sumatra.cam.proto.SslVisionGeometry;
import edu.tigers.sumatra.model.SumatraModel;
import edu.tigers.sumatra.referee.AReferee;
import edu.tigers.sumatra.referee.proto.SslGcRefereeMessage;
import edu.tigers.sumatra.referee.source.DirectRefereeMsgForwarder;
import edu.tigers.sumatra.referee.source.ERefereeMessageSource;
import edu.tigers.sumatra.vision.AVisionFilter;
import edu.tigers.sumatra.vision.data.FilteredVisionFrame;
import edu.tigers.sumatra.wp.IWorldFrameObserver;
import edu.tigers.sumatra.wp.TrackerPacketGenerator;
import edu.tigers.sumatra.wp.WorldInfoCollector;
import edu.tigers.sumatra.wp.data.WorldFrameWrapper;
import edu.tigers.sumatra.wp.proto.SslVisionWrapperTracked;
import edu.tigers.sumatra.wp.proto.SslVisionWrapperTracked.TrackerWrapperPacket;


public class AutoRefereeCiCamModule extends ACam implements IWorldFrameObserver
{
private final SSLVisionCamGeometryTranslator geometryTranslator = new SSLVisionCamGeometryTranslator();
private final TrackedFrameToFilteredVisionMapper trackedFrameToFilteredVisionMapper = new TrackedFrameToFilteredVisionMapper();
private final TrackerPacketGenerator trackerPacketGenerator = new TrackerPacketGenerator("TIGERs");
private final AutoRefereeCiServer autoRefereeCiServer = new AutoRefereeCiServer(
this::publishDetection,
this::publishGeometry,
this::publishReferee,
this::publishTrackedWrapperFrame
);

private DirectRefereeMsgForwarder refForwarder;


@Override
public void startModule() throws StartModuleException
{
super.startModule();
SumatraModel.getInstance().getModule(WorldInfoCollector.class).addObserver(this);
AReferee ref = SumatraModel.getInstance().getModule(AReferee.class);
refForwarder = (DirectRefereeMsgForwarder) ref.getSource(ERefereeMessageSource.INTERNAL_FORWARDER);
int port = getSubnodeConfiguration().getInt("port", 10013);
autoRefereeCiServer.setPort(port);
autoRefereeCiServer.start();
}


@Override
public void stopModule()
{
autoRefereeCiServer.stop();
super.stopModule();
}


@Override
public void onNewWorldFrame(final WorldFrameWrapper wfw)
{
SslVisionWrapperTracked.TrackerWrapperPacket packet = trackerPacketGenerator.generate(wfw.getSimpleWorldFrame());
autoRefereeCiServer.publish(packet);
}


private void publishReferee(SslGcRefereeMessage.Referee referee)
{
refForwarder.send(referee);
}


private void publishGeometry(SslVisionGeometry.SSL_GeometryData geometryData)
{
CamGeometry geometry = geometryTranslator.fromProtobuf(geometryData);
notifyNewCameraCalibration(geometry);
}


private void publishDetection(SslVisionDetection.SSL_DetectionFrame detectionFrame)
{
notifyNewCameraFrame(detectionFrame);
}


private void publishTrackedWrapperFrame(TrackerWrapperPacket wrapper)
{
FilteredVisionFrame filteredVisionFrame = trackedFrameToFilteredVisionMapper.map(wrapper.getTrackedFrame());
SumatraModel.getInstance().getModule(AVisionFilter.class).publishFilteredVisionFrame(filteredVisionFrame);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
/*
* Copyright (c) 2009 - 2022, DHBW Mannheim - TIGERs Mannheim
*/

package edu.tigers.autoreferee.ci;

import edu.tigers.autoreferee.proto.SslAutorefCi.AutoRefCiInput;
import edu.tigers.autoreferee.proto.SslAutorefCi.AutoRefCiOutput;
import edu.tigers.sumatra.cam.proto.SslVisionDetection;
import edu.tigers.sumatra.cam.proto.SslVisionGeometry;
import edu.tigers.sumatra.referee.proto.SslGcRefereeMessage;
import edu.tigers.sumatra.util.Safe;
import edu.tigers.sumatra.wp.proto.SslVisionWrapperTracked;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.extern.log4j.Log4j2;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.function.Consumer;


@Log4j2
@RequiredArgsConstructor
public class AutoRefereeCiServer
{
private final Consumer<SslVisionDetection.SSL_DetectionFrame> detectionFrameConsumer;
private final Consumer<SslVisionGeometry.SSL_GeometryData> geometryDataConsumer;
private final Consumer<SslGcRefereeMessage.Referee> refereeConsumer;
private final Consumer<SslVisionWrapperTracked.TrackerWrapperPacket> trackerWrapperPacketConsumer;

@Setter
private int port;
private Thread thread;
private boolean running;
private ServerSocket serverSocket;
private Socket currentSocket;


public void start()
{
if (running)
{
throw new IllegalStateException("Server is already running");
}
running = true;
try
{
serverSocket = new ServerSocket(port);
} catch (IOException e)
{
log.error("Could not listen on port " + port, e);
return;
}
thread = new Thread(() -> Safe.run(this::listen));
thread.setName("AutoRef CI Server");
thread.start();
}


public void stop()
{
if (!running)
{
throw new IllegalStateException("Server is already stopped");
}
running = false;
try
{
serverSocket.close();
} catch (IOException e)
{
log.warn("Failed to close server socket", e);
}

thread.interrupt();
thread = null;
serverSocket = null;
}


public void publish(SslVisionWrapperTracked.TrackerWrapperPacket trackerWrapperPacket)
{
Socket socket = currentSocket;
if (socket == null)
{
return;
}

AutoRefCiOutput autoRefCiOutput = AutoRefCiOutput.newBuilder()
.setTrackerWrapperPacket(trackerWrapperPacket)
.build();
try
{
autoRefCiOutput.writeDelimitedTo(socket.getOutputStream());
} catch (IOException e)
{
log.warn("Failed to publish tracker wrapper packet", e);
}
}


private void listen()
{
while (running)
{
try
{
currentSocket = accept();
while (running)
{
if (!consume(currentSocket))
{
break;
}
}
} catch (IOException e)
{
log.warn("Connection failed", e);
}
currentSocket = null;
}
}


private boolean consume(Socket socket) throws IOException
{
if (socket == null)
{
return false;
}
AutoRefCiInput autoRefCiInput = AutoRefCiInput.parseDelimitedFrom(socket.getInputStream());
if (autoRefCiInput == null)
{
return false;
}
if (autoRefCiInput.hasGeometry())
{
geometryDataConsumer.accept(autoRefCiInput.getGeometry());
}
autoRefCiInput.getDetectionList().forEach(detectionFrameConsumer);
if (autoRefCiInput.hasRefereeMessage())
{
refereeConsumer.accept(autoRefCiInput.getRefereeMessage());
}
if (autoRefCiInput.hasTrackerWrapperPacket())
{
trackerWrapperPacketConsumer.accept(autoRefCiInput.getTrackerWrapperPacket());
}
return true;
}


private Socket accept() throws IOException
{
Socket socket = serverSocket.accept();
socket.setTcpNoDelay(true);
return socket;
}
}
Loading

0 comments on commit 380962e

Please sign in to comment.