Skip to content

Commit bf7ec9b

Browse files
committed
Feature: Add test clients for tracking protocol
1 parent 05fa778 commit bf7ec9b

File tree

2 files changed

+196
-0
lines changed
  • cmd
    • ssl-tracker-consumer-test-client
    • ssl-tracker-producer-test-client

2 files changed

+196
-0
lines changed
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package main
2+
3+
import (
4+
"flag"
5+
"fmt"
6+
"github.com/RoboCup-SSL/ssl-game-controller/internal/app/tracker"
7+
"github.com/golang/protobuf/proto"
8+
"log"
9+
"net"
10+
"sort"
11+
"time"
12+
)
13+
14+
const maxDatagramSize = 8192
15+
16+
var trackerAddress = flag.String("address", "224.5.23.2:10010", "The multicast address of the tracker")
17+
var fullScreen = flag.Bool("fullScreen", false, "Print the formatted message to the console, clearing the screen during print")
18+
19+
func main() {
20+
flag.Parse()
21+
22+
addr, err := net.ResolveUDPAddr("udp", *trackerAddress)
23+
if err != nil {
24+
log.Fatal(err)
25+
}
26+
conn, err := net.ListenMulticastUDP("udp", nil, addr)
27+
if err != nil {
28+
log.Fatal(err)
29+
}
30+
31+
if err := conn.SetReadBuffer(maxDatagramSize); err != nil {
32+
log.Printf("Could not set read buffer to %v.", maxDatagramSize)
33+
}
34+
log.Println("Receiving from", *trackerAddress)
35+
36+
sourcePackets := map[string]*tracker.TrackerWrapperPacket{}
37+
b := make([]byte, maxDatagramSize)
38+
for {
39+
n, err := conn.Read(b)
40+
if err != nil {
41+
log.Print("Could not read", err)
42+
time.Sleep(1 * time.Second)
43+
continue
44+
}
45+
if n >= maxDatagramSize {
46+
log.Fatal("Buffer size too small")
47+
}
48+
packet := tracker.TrackerWrapperPacket{}
49+
if err := proto.Unmarshal(b[0:n], &packet); err != nil {
50+
log.Println("Could not unmarshal referee message")
51+
continue
52+
}
53+
sourcePackets[*packet.Uuid] = &packet
54+
55+
if *fullScreen {
56+
// clear screen, move cursor to upper left corner
57+
fmt.Print("\033[H\033[2J")
58+
59+
var sources []string
60+
for source := range sourcePackets {
61+
sources = append(sources, source)
62+
}
63+
sort.Strings(sources)
64+
65+
// print message formatted with line breaks
66+
for _, source := range sources {
67+
fmt.Print(proto.MarshalTextString(sourcePackets[source]))
68+
}
69+
} else {
70+
log.Print(proto.CompactTextString(&packet))
71+
}
72+
}
73+
}
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
package main
2+
3+
import (
4+
"bufio"
5+
"flag"
6+
"fmt"
7+
"github.com/RoboCup-SSL/ssl-game-controller/internal/app/geom"
8+
"github.com/RoboCup-SSL/ssl-game-controller/internal/app/tracker"
9+
"github.com/golang/protobuf/proto"
10+
"github.com/odeke-em/go-uuid"
11+
"log"
12+
"net"
13+
"os"
14+
"strconv"
15+
"strings"
16+
"time"
17+
)
18+
19+
const maxDatagramSize = 8192
20+
21+
var sourceName = flag.String("sourceName", "tracker-test-client", "The name of the client")
22+
var trackerAddress = flag.String("address", "224.5.23.2:10010", "The multicast address of the tracker")
23+
24+
func main() {
25+
flag.Parse()
26+
27+
addr, err := net.ResolveUDPAddr("udp", *trackerAddress)
28+
if err != nil {
29+
log.Fatal(err)
30+
}
31+
conn, err := net.DialUDP("udp", nil, addr)
32+
if err != nil {
33+
log.Fatal(err)
34+
}
35+
36+
if err := conn.SetReadBuffer(maxDatagramSize); err != nil {
37+
log.Printf("Could not set read buffer to %v.", maxDatagramSize)
38+
}
39+
40+
frame := tracker.TrackedFrame{
41+
FrameNumber: new(uint32),
42+
Timestamp: new(float64),
43+
Balls: []*tracker.TrackedBall{
44+
{
45+
Pos: &geom.Vector3{
46+
X: new(float32),
47+
Y: new(float32),
48+
Z: new(float32),
49+
},
50+
Vel: &geom.Vector3{
51+
X: new(float32),
52+
Y: new(float32),
53+
Z: new(float32),
54+
},
55+
},
56+
},
57+
}
58+
59+
commands := map[string]func([]string){}
60+
commands["ballpos"] = func(args []string) {
61+
if len(args) != 3 {
62+
log.Printf("x, y, z required")
63+
} else {
64+
x, _ := strconv.ParseFloat(args[0], 32)
65+
y, _ := strconv.ParseFloat(args[1], 32)
66+
z, _ := strconv.ParseFloat(args[2], 32)
67+
*frame.Balls[0].Pos.X = float32(x)
68+
*frame.Balls[0].Pos.Y = float32(y)
69+
*frame.Balls[0].Pos.Z = float32(z)
70+
log.Printf("Ball changed: %v", *frame.Balls[0])
71+
}
72+
}
73+
74+
go publish(frame, conn)
75+
76+
reader := bufio.NewReader(os.Stdin)
77+
for {
78+
fmt.Print("-> ")
79+
text, err := reader.ReadString('\n')
80+
if err != nil {
81+
log.Print("Can not read from stdin: ", err)
82+
for {
83+
time.Sleep(1 * time.Second)
84+
}
85+
}
86+
// convert CRLF to LF
87+
text = strings.Replace(text, "\n", "", -1)
88+
cmd := strings.Split(text, " ")
89+
if fn, ok := commands[cmd[0]]; ok {
90+
fn(cmd[1:])
91+
} else {
92+
fmt.Println("Available commands:")
93+
for cmd := range commands {
94+
fmt.Printf(" %-20s\n", cmd)
95+
}
96+
}
97+
}
98+
}
99+
100+
func publish(frame tracker.TrackedFrame, conn *net.UDPConn) {
101+
id := uuid.New()
102+
wrapperPacket := tracker.TrackerWrapperPacket{
103+
Uuid: &id,
104+
SourceName: sourceName,
105+
TrackedFrame: &frame,
106+
}
107+
108+
log.Println("Sending to ", *trackerAddress)
109+
for {
110+
*frame.Timestamp = float64(time.Now().UnixNano()) / 1e9
111+
if bytes, err := proto.Marshal(&wrapperPacket); err != nil {
112+
log.Printf("Could not marshal packet: %v\nError: %v", wrapperPacket, err)
113+
return
114+
} else {
115+
if _, err = conn.Write(bytes); err != nil {
116+
log.Printf("Could not write message: %v", err)
117+
return
118+
}
119+
}
120+
time.Sleep(time.Millisecond * 10)
121+
*frame.FrameNumber++
122+
}
123+
}

0 commit comments

Comments
 (0)