Skip to content

Commit

Permalink
improve declare/snaplock parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
dharmab committed Sep 17, 2024
1 parent 96f117a commit 5b1a4c5
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 36 deletions.
1 change: 1 addition & 0 deletions docs/PLAYER.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ Some types of requests require you to provide numeric arguments.
* Do not use ICAO pronunciation; pronounce numbers normally. Say "Three", "Five", "Nine", not "Tree", "Fife", "Niner".
* When providing bullseye coordinates, you may either say "bullseye" before the coordinates, or omit the word "bullseye". That is, both "Bullseye Zero Six Five, Ninety-Nine" and "Zero Six Five, Ninety-Nine" are acceptable.
* When providing bullseye coordinates, speak at a steady and measured pace with a slight pause between each number. Not too fast, not too slow. Don't mush your numbers together.
* If the bot has trouble understanding your bullseye coordinates, you may use the separators "at" or "altitude" between the range and altitude. That is "Bullseye Zero Six Five, Ninety-Nine, at Twelve Thousand"

Tips:

Expand Down
14 changes: 10 additions & 4 deletions pkg/controller/declare.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,16 @@ func (c *controller) HandleDeclare(request *brevity.DeclareRequest) {
}
pointOfInterest := spatial.PointAtBearingAndDistance(origin, bearing, distance)

radius := 7 * unit.NauticalMile // TODO reduce to 3 when magvar is available
altitudeMargin := unit.Length(5000) * unit.Foot
minAltitude := request.Altitude - altitudeMargin
maxAltitude := request.Altitude + altitudeMargin
radius := 7 * unit.NauticalMile

minAltitude := lowestAltitude
maxAltitude := highestAltitude
if request.Altitude != 0 {
altitudeMargin := unit.Length(5000) * unit.Foot
minAltitude = request.Altitude - altitudeMargin
maxAltitude = request.Altitude + altitudeMargin
}

friendlyGroups := c.scope.FindNearbyGroupsWithBullseye(pointOfInterest, minAltitude, maxAltitude, radius, c.coalition, brevity.Aircraft, []uint64{trackfile.Contact.ID})
hostileGroups := c.scope.FindNearbyGroupsWithBullseye(pointOfInterest, minAltitude, maxAltitude, radius, c.coalition.Opposite(), brevity.Aircraft, []uint64{trackfile.Contact.ID})
logger.Debug().Int("friendly", len(friendlyGroups)).Int("hostile", len(hostileGroups)).Msg("queried groups near declared location")
Expand Down
5 changes: 2 additions & 3 deletions pkg/parser/declare.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,9 @@ func (p *parser) parseDeclare(callsign string, scanner *bufio.Scanner) (*brevity
}

altitude, ok := p.parseAltitude(scanner)
if !ok {
return nil, false
if ok {
log.Debug().Int("altitude", int(altitude.Feet())).Msg("parsed altitude")
}
log.Debug().Int("altitude", int(altitude.Feet())).Msg("parsed altitude")

track := p.parseTrack(scanner)
log.Debug().Str("track", string(track)).Msg("parsed track")
Expand Down
63 changes: 63 additions & 0 deletions pkg/parser/declare_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,66 @@ import (
func TestParserDeclare(t *testing.T) {
t.Parallel()
testCases := []parserTestCase{
{
text: "anyface, chevy one one, declare, 075 26 2000",
expected: &brevity.DeclareRequest{
Callsign: "chevy 1 1",
Bullseye: *brevity.NewBullseye(
bearings.NewMagneticBearing(75*unit.Degree),
26*unit.NauticalMile,
),
Altitude: 2000 * unit.Foot,
Track: brevity.UnknownDirection,
},
},
{
text: "anyface, chevy one one, declare, 075 26",
expected: &brevity.DeclareRequest{
Callsign: "chevy 1 1",
Bullseye: *brevity.NewBullseye(
bearings.NewMagneticBearing(75*unit.Degree),
26*unit.NauticalMile,
),
Altitude: 0,
Track: brevity.UnknownDirection,
},
},
{
text: "anyface, chevy one one, declare, 075 26 at 2000",
expected: &brevity.DeclareRequest{
Callsign: "chevy 1 1",
Bullseye: *brevity.NewBullseye(
bearings.NewMagneticBearing(75*unit.Degree),
26*unit.NauticalMile,
),
Altitude: 2000 * unit.Foot,
Track: brevity.UnknownDirection,
},
},
{
text: "anyface, chevy one one, declare bullseye 075 for 26 at 2000",
expected: &brevity.DeclareRequest{
Callsign: "chevy 1 1",
Bullseye: *brevity.NewBullseye(
bearings.NewMagneticBearing(75*unit.Degree),
26*unit.NauticalMile,
),
Altitude: 2000 * unit.Foot,
Track: brevity.UnknownDirection,
},
},
{
text: "anyface, chevy one one, declare, 075 26 altitude 2000",
expected: &brevity.DeclareRequest{
Callsign: "chevy 1 1",
Bullseye: *brevity.NewBullseye(
bearings.NewMagneticBearing(75*unit.Degree),
26*unit.NauticalMile,
),
Altitude: 2000 * unit.Foot,
Track: brevity.UnknownDirection,
},
},
{
text: "anyface, tater 1-1, declare bullseye 0-5-4, 123, 3000",
expected: &brevity.DeclareRequest{
Expand Down Expand Up @@ -125,13 +185,16 @@ func TestParserDeclare(t *testing.T) {
assert.Equal(t, expected.Callsign, actual.Callsign)
if expected.IsBRAA {
assert.True(t, actual.IsBRAA)
require.NotNil(t, actual)
require.NotNil(t, actual.Bearing)
assert.InDelta(t, expected.Bearing.Degrees(), actual.Bearing.Degrees(), 0.5)
require.NotNil(t, actual.Range)
assert.InDelta(t, expected.Range.NauticalMiles(), actual.Range.NauticalMiles(), 0.5)
} else {
assert.False(t, actual.IsBRAA)
require.NotNil(t, actual)
require.NotNil(t, actual.Bullseye)
require.NotNil(t, actual.Bullseye.Bearing())
assert.InDelta(t, expected.Bullseye.Bearing().Degrees(), actual.Bullseye.Bearing().Degrees(), 0.5)
assert.InDelta(t, expected.Bullseye.Distance().NauticalMiles(), actual.Bullseye.Distance().NauticalMiles(), 1)
}
Expand Down
9 changes: 9 additions & 0 deletions pkg/parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -299,3 +299,12 @@ func ParsePilotCallsign(tx string) (callsign string, isValid bool) {

return callsign, true
}

func skipWords(scanner *bufio.Scanner, words ...string) bool {
for _, word := range words {
if IsSimilar(scanner.Text(), word) {
return scanner.Scan()
}
}
return true
}
11 changes: 11 additions & 0 deletions pkg/parser/snaplock_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,17 @@ func TestParserSnaplock(t *testing.T) {
),
},
},
{
text: "Anyface Fox 1 2 snaplock 058 for 147 at 3000",
expected: &brevity.SnaplockRequest{
Callsign: "fox 1 2",
BRA: brevity.NewBRA(
bearings.NewMagneticBearing(58*unit.Degree),
147*unit.NauticalMile,
3000*unit.Foot,
),
},
},
}
runParserTestCases(t, New(TestCallsign, true), testCases, func(t *testing.T, test parserTestCase, request any) {
t.Helper()
Expand Down
47 changes: 18 additions & 29 deletions pkg/parser/spatial.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,27 +13,15 @@ import (
var bullseyeWords = []string{"bullseye", "bulls"}

func (p *parser) parseBullseye(scanner *bufio.Scanner) *brevity.Bullseye {
for _, word := range bullseyeWords {
if IsSimilar(scanner.Text(), word) {
ok := scanner.Scan()
if !ok {
return nil
}
}
if !skipWords(scanner, bullseyeWords...) {
return nil
}

b, ok := p.parseBearing(scanner)
if !ok {
return nil
}

for scanner.Text() == "for" {
ok := scanner.Scan()
if !ok {
return nil
}
}

r, ok := p.parseRange(scanner)
if !ok {
return nil
Expand All @@ -45,15 +33,9 @@ func (p *parser) parseBullseye(scanner *bufio.Scanner) *brevity.Bullseye {
var braaWords = []string{"bra", "brah", "braa"}

func (p *parser) parseBRA(scanner *bufio.Scanner) (brevity.BRA, bool) {
for _, word := range braaWords {
if IsSimilar(scanner.Text(), word) {
ok := scanner.Scan()
if !ok {
return nil, false
}
}
if !skipWords(scanner, braaWords...) {
return nil, false
}

b, ok := p.parseBearing(scanner)
if !ok {
return nil, false
Expand Down Expand Up @@ -103,17 +85,29 @@ func (p *parser) parseBearing(scanner *bufio.Scanner) (bearings.Bearing, bool) {

// parseRange parses a distance. The number must be pronounced as a whole cardinal number.
func (p *parser) parseRange(scanner *bufio.Scanner) (unit.Length, bool) {
if !scanner.Scan() {
return 0, false
}
if !skipWords(scanner, "for") {
return 0, false
}
d, ok := p.parseNaturalNumber(scanner)
if !ok {
return 0 * unit.NauticalMile, false
return 0, false
}
return unit.Length(d) * unit.NauticalMile, true
}

func (p *parser) parseAltitude(scanner *bufio.Scanner) (unit.Length, bool) {
if !scanner.Scan() {
return 0, false
}
if !skipWords(scanner, "at", "altitude") {
return 0, false
}
d, ok := p.parseNaturalNumber(scanner)
if !ok {
return 0 * unit.Foot, false
return 0, false
}
return unit.Length(d) * unit.Foot, true
}
Expand Down Expand Up @@ -149,11 +143,6 @@ func (p *parser) parseTrack(scanner *bufio.Scanner) brevity.Track {
}

func (p *parser) parseNaturalNumber(scanner *bufio.Scanner) (int, bool) {
if !scanner.Scan() {
log.Debug().Msg("nothing left to scan")
return 0, false
}

s := scanner.Text()
d, err := numwords.ParseInt(s)
if err != nil {
Expand Down

0 comments on commit 5b1a4c5

Please sign in to comment.