Skip to content

Commit 3c77b82

Browse files
committed
Add sample client for the autoRef CI protocol
1 parent 241e1fa commit 3c77b82

File tree

7 files changed

+436
-1
lines changed

7 files changed

+436
-1
lines changed

cmd/ssl-auto-ref-ci-client/README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# ssl-auto-ref-ci-client
2+
3+
This folder contains a sample client that connects to the CI interface of an autoRef and the game-controller.
4+
5+
## Protocol
6+
The communication is established with a bidirectional TCP connection. Messages are encoded with [Protocol Buffers](https://developers.google.com/protocol-buffers/). Each message is preceded by an uvarint containing the message size in bytes, see https://cwiki.apache.org/confluence/display/GEODE/Delimiting+Protobuf+Messages for details.
7+
8+
The protobuf format can be found in [../../proto/ssl_autoref_ci.proto](../../proto/ssl_autoref_ci.proto).
9+
10+
The default port is `10013`.
11+
12+
## Sample client
13+
The sample client, that is included in this folder, can be used to test the connection. It can be run with
14+
```bash
15+
go run cmd/ssl-auto-ref-ci-client/main.go
16+
```
17+
Pass it the `-h` parameter to get the available options.

cmd/ssl-auto-ref-ci-client/main.go

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
package main
2+
3+
import (
4+
"bufio"
5+
"flag"
6+
"github.com/RoboCup-SSL/ssl-game-controller/internal/app/ci"
7+
"github.com/RoboCup-SSL/ssl-game-controller/internal/app/ci/autoref"
8+
"github.com/RoboCup-SSL/ssl-game-controller/internal/app/sslconn"
9+
"github.com/RoboCup-SSL/ssl-game-controller/internal/app/state"
10+
"github.com/RoboCup-SSL/ssl-game-controller/internal/app/tracker"
11+
"github.com/RoboCup-SSL/ssl-game-controller/internal/app/vision"
12+
"github.com/google/uuid"
13+
"log"
14+
"net"
15+
"time"
16+
)
17+
18+
var addressAutoRefCi = flag.String("addressAutoRef", "localhost:10013", "The address of the auto referee CI interface")
19+
var addressGcCi = flag.String("addressGc", "localhost:10009", "The address of the ssl-game-controller CI interface")
20+
21+
var id = uuid.NewString()
22+
var name = "Test client"
23+
var detectionFrame = createSSlDetectionFrame()
24+
var refereeMsg *state.Referee
25+
var robotSpeed = float32(1)
26+
27+
func main() {
28+
flag.Parse()
29+
30+
autoRefConn := connect(*addressAutoRefCi)
31+
gcConn := connect(*addressGcCi)
32+
33+
for {
34+
simulate()
35+
sendAutoRefCi(autoRefConn, detectionFrame)
36+
trackerFrame := receiveAutoRefCi(autoRefConn)
37+
sendCi(gcConn, trackerFrame)
38+
refereeMsg = receiveCi(gcConn)
39+
time.Sleep(10 * time.Millisecond)
40+
}
41+
}
42+
43+
func simulate() {
44+
robotX := detectionFrame.RobotsBlue[0].X
45+
*robotX += robotSpeed / 100 * 1000
46+
if *robotX > 2000 || *robotX < -2000 {
47+
robotSpeed *= -1
48+
}
49+
}
50+
51+
func connect(addr string) (conn net.Conn) {
52+
conn, err := net.Dial("tcp", addr)
53+
if err != nil {
54+
log.Fatal("could not connect to ", addr)
55+
}
56+
log.Printf("Connected to %v", addr)
57+
return
58+
}
59+
60+
func createBall() (ball *vision.SSL_DetectionBall) {
61+
ball = new(vision.SSL_DetectionBall)
62+
ball.Confidence = new(float32)
63+
ball.PixelX = new(float32)
64+
ball.PixelY = new(float32)
65+
ball.X = new(float32)
66+
ball.Y = new(float32)
67+
*ball.Confidence = 1
68+
return
69+
}
70+
71+
func createBot() (robot *vision.SSL_DetectionRobot) {
72+
robot = new(vision.SSL_DetectionRobot)
73+
robot.Confidence = new(float32)
74+
robot.RobotId = new(uint32)
75+
robot.PixelX = new(float32)
76+
robot.PixelY = new(float32)
77+
robot.X = new(float32)
78+
robot.Y = new(float32)
79+
robot.Orientation = new(float32)
80+
*robot.Confidence = 1
81+
return
82+
}
83+
84+
func createSSlDetectionFrame() (p *vision.SSL_DetectionFrame) {
85+
p = new(vision.SSL_DetectionFrame)
86+
p.FrameNumber = new(uint32)
87+
p.TSent = new(float64)
88+
p.TCapture = new(float64)
89+
p.CameraId = new(uint32)
90+
p.Balls = []*vision.SSL_DetectionBall{createBall()}
91+
p.RobotsBlue = []*vision.SSL_DetectionRobot{createBot()}
92+
return
93+
}
94+
95+
func sendCi(conn net.Conn, trackerPacket *tracker.TrackerWrapperPacket) {
96+
timestamp := time.Now().UnixNano()
97+
*trackerPacket.TrackedFrame.Timestamp = float64(timestamp / 1e9)
98+
*trackerPacket.TrackedFrame.FrameNumber++
99+
input := ci.CiInput{Timestamp: &timestamp, TrackerPacket: trackerPacket}
100+
if err := sslconn.SendMessage(conn, &input); err != nil {
101+
log.Println("Could not send message: ", err)
102+
}
103+
}
104+
105+
func receiveCi(conn net.Conn) *state.Referee {
106+
reader := bufio.NewReaderSize(conn, 1)
107+
output := ci.CiOutput{}
108+
if err := sslconn.ReceiveMessage(reader, &output); err != nil {
109+
log.Println("Could not receive message: ", err)
110+
}
111+
return output.RefereeMsg
112+
}
113+
114+
func sendAutoRefCi(conn net.Conn, detectionFrame *vision.SSL_DetectionFrame) {
115+
timestamp := time.Now().UnixNano()
116+
117+
*detectionFrame.TSent = float64(timestamp / 1e9)
118+
*detectionFrame.TCapture = float64(timestamp / 1e9)
119+
*detectionFrame.FrameNumber++
120+
input := autoref.AutoRefCiInput{
121+
Detection: []*vision.SSL_DetectionFrame{detectionFrame},
122+
RefereeMessage: refereeMsg,
123+
}
124+
if err := sslconn.SendMessage(conn, &input); err != nil {
125+
log.Println("Could not send message: ", err)
126+
}
127+
}
128+
129+
func receiveAutoRefCi(conn net.Conn) *tracker.TrackerWrapperPacket {
130+
reader := bufio.NewReaderSize(conn, 1)
131+
output := autoref.AutoRefCiOutput{}
132+
if err := sslconn.ReceiveMessage(reader, &output); err != nil {
133+
log.Println("Could not receive message: ", err)
134+
}
135+
return output.TrackerWrapperPacket
136+
}

doc/AutoRefCi.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
To ease integration of the ssl-game-controller and the auto-referee implementations, there are separate unicast protocols that avoid the asynchronous communication via multicast and allows for integration with simulators and running at non-realtime speeds.
44

5+
The default port is `10013`.
6+
57
## Connection sequence
68

79
The connection is described in the following sequence diagram:

generateProto.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ protoc -I"./proto" -I"$GOPATH/src" --go_out="$GOPATH/src" proto/ssl_gc_engine_co
4242

4343
# continuous integration communication
4444
protoc -I"./proto" -I"$GOPATH/src" --go_out="$GOPATH/src" proto/ssl_gc_ci.proto
45+
protoc -I"./proto" -I"$GOPATH/src" --go_out="$GOPATH/src" proto/ssl_autoref_ci.proto
4546

4647
# generate javascript code
4748
pbjs -t static-module -w es6 -o src/proto.js \

0 commit comments

Comments
 (0)