Skip to content

Commit dc29901

Browse files
Merge pull request #203 from CPSSD/feature/Localization
Feature/localization
2 parents 01e0db7 + 43bb678 commit dc29901

File tree

8 files changed

+206
-80
lines changed

8 files changed

+206
-80
lines changed

source/edison/src/RobotDriverProtocol/RobotDriverProtocol.go

+6-4
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ func processCompassResponse(responseBuffer []uint8) {
130130
compassResponse.ID = (uint16(responseBuffer[0]) << 8) + uint16(responseBuffer[1])
131131
compassResponse.Angle = (uint16(responseBuffer[2]) << 8) + uint16(responseBuffer[3])
132132
compassResponse.Success = (responseBuffer[4] > 0)
133+
fmt.Println("Passing compassResponse to responseHandler")
134+
fireResponseHandler(compassResponse)
133135
}
134136

135137
// processResponse will process a response
@@ -158,7 +160,7 @@ func sendNextCommand() bool {
158160

159161
data := make([]uint8, 1)
160162
data[0] = length
161-
time.Sleep(time.Millisecond/10)
163+
time.Sleep(time.Millisecond / 10)
162164
SPI.TransferAndReceiveData(data)
163165
if data[0] > length {
164166
length = data[0]
@@ -173,10 +175,10 @@ func sendNextCommand() bool {
173175
buffersToSend = buffersToSend[1:]
174176
}
175177

176-
time.Sleep(time.Millisecond/10)
178+
time.Sleep(time.Millisecond / 10)
177179

178180
for i := 0; i < len(dataBuffer); i++ {
179-
time.Sleep(time.Millisecond/10)
181+
time.Sleep(time.Millisecond / 10)
180182
data[0] = dataBuffer[i]
181183
SPI.TransferAndReceiveData(data)
182184
dataBuffer[i] = data[0]
@@ -193,7 +195,7 @@ func sendNextCommand() bool {
193195
notFinished = true
194196
}
195197

196-
time.Sleep(time.Millisecond/10)
198+
time.Sleep(time.Millisecond / 10)
197199
SPI.TransferAndReceiveData(data)
198200

199201
return (notFinished == true || data[0] == 1)

source/edison/src/mapping/maps/RDPIntegration.go

+26-10
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,6 @@ func RDPInit() {
1717

1818
// RDPConnector handles the incoming data.
1919
func RDPConnector(data interface{}) {
20-
// fmt.Println()
21-
// fmt.Println("\tData Recieved =>", data)
22-
2320
switch response := data.(type) {
2421
case RobotDriverProtocol.MoveResponse:
2522
moveResponse(response)
@@ -29,12 +26,26 @@ func RDPConnector(data interface{}) {
2926
scanResponse(response)
3027
case RobotDriverProtocol.StopResponse:
3128
stopResponse(response)
29+
case RobotDriverProtocol.CompassResponse:
30+
compassResponse(response)
3231
}
3332
}
3433

34+
func compassResponse(response RobotDriverProtocol.CompassResponse) {
35+
fmt.Println("[Compass Response] Angle: ", response.Angle)
36+
UpdateCompassHeading(int(response.Angle))
37+
}
38+
3539
func moveResponse(response RobotDriverProtocol.MoveResponse) {
3640
fmt.Print("[Move Response] Angle:", response.Angle, " // Magnitude:", response.Magnitude)
37-
// fmt.Println("\t[Response] { ID:", response.ID, " // Type:", response.Type, "}")
41+
42+
if !response.Success {
43+
fmt.Println("Problem moving... Doing a scan.");
44+
followingPath = false
45+
RobotMap.MoveRobotAlongLine(float64(response.Angle), float64(response.Magnitude))
46+
RobotDriverProtocol.Scan()
47+
return
48+
}
3849

3950
if followingPath {
4051
lastX := RobotMap.GetRobot().GetX()
@@ -54,7 +65,6 @@ func moveResponse(response RobotDriverProtocol.MoveResponse) {
5465

5566
func scanResponse(response RobotDriverProtocol.ScanResponse) {
5667
fmt.Println("[Scan Response] Degree: ", response.Degree, " // Distance: ", response.Distance)
57-
// fmt.Println("\t[Response] { ID:", response.ID, " // Type:", response.Type, "}")
5868

5969
// Add a wall at the specific location.
6070
// When last response, find next location to move to in map.go
@@ -63,20 +73,26 @@ func scanResponse(response RobotDriverProtocol.ScanResponse) {
6373
if response.Last {
6474
if firstScan {
6575
firstScan = false
66-
RobotMap.addBufferToMap()
76+
if CurrentlyMapping {
77+
RobotMap.addBufferToMap()
78+
}
6779
} else {
6880
fmt.Println("Robot should be here at this location: (", RobotMap.GetRobot().GetX(), ", ", RobotMap.GetRobot().GetY(), ")")
69-
x, y, rotation := RobotMap.FindLocation()
81+
x, y, rotation := RobotMap.FindLocation(200 / BitmapScale, 20, 1)
7082
RobotMap.GetRobot().MoveToPoint(x, y, true)
7183
RobotMap.GetRobot().Rotate(float64(rotation))
72-
RobotMap.addBufferToMap()
84+
if CurrentlyMapping {
85+
RobotMap.addBufferToMap()
86+
}
7387
}
7488

7589
lastAction = "Scan"
7690
currentID = -1
7791

7892
RobotMap.Print(nil)
79-
RobotMap.ContinueToNextArea()
93+
if CurrentlyMapping {
94+
RobotMap.ContinueToNextArea()
95+
}
8096
}
8197
}
8298

@@ -99,7 +115,7 @@ func stopResponse(response RobotDriverProtocol.StopResponse) {
99115
RobotMap.MoveRobotAlongLine(float64(response.Angle), float64(response.Magnitude))
100116
lastAction = "Stop"
101117
currentID = -1
102-
118+
followingPath = false
103119
RobotDriverProtocol.Scan()
104120

105121
}

source/edison/src/mapping/maps/line.go

+8
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,14 @@ type Line struct {
1414
Slope int
1515
}
1616

17+
func (this Line) split() (Line, Line) {
18+
midPoint := Point{(this.P1.X + this.P2.X) / 2, (this.P1.Y + this.P2.Y) / 2}
19+
line1, line2 := Line{P1: this.P1, P2: midPoint}, Line{P1: midPoint, P2: this.P2}
20+
line1.Slope, line1.Vertical = line1.getSlope()
21+
line2.Slope, line2.Vertical = line2.getSlope()
22+
return line1, line2
23+
}
24+
1725
// Gets the slope of the line. Returns (slope int, vertical bool). If vertical, Slope will be set to 0.
1826
func (this Line) getSlope() (int, bool) {
1927
if this.P1.X == this.P2.X {

source/edison/src/mapping/maps/map.go

+80-41
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,20 @@ const Debug = false
1818
var BitmapScale int
1919
var scanBuffer []RobotDriverProtocol.ScanResponse
2020
var finishedMapping = false
21+
var CurrentlyMapping = true
2122

2223
// RobotMap is the current environment being mapped
2324
var firstScan = true
2425
var checkLocation = false
2526
var followingPath = false
2627

28+
var compassOffset = -1
29+
var compassHeading = 0
30+
var waitingForHeading = false
31+
32+
var distanceSinceLastScan = 0
33+
var minimumScanDistance = 50
34+
2735
var pathIndex = 0
2836

2937
// RobotMap is a map of the current room being mapped
@@ -57,10 +65,6 @@ func MapInit(bitmapScale int) {
5765
fmt.Println("[RDP Link Ready]")
5866

5967
scanBuffer = make([]RobotDriverProtocol.ScanResponse, 0)
60-
61-
defer RobotMap.Print(nil)
62-
63-
RobotDriverProtocol.Scan()
6468
}
6569

6670
// GetSeenMap returns the seen map.
@@ -78,11 +82,23 @@ func (this *Map) GetRobot() *Robot {
7882
return &this.robot
7983
}
8084

85+
func UpdateCompassHeading(angle int) {
86+
if compassOffset == -1 {
87+
compassOffset = angle
88+
}
89+
compassHeading = (angle - compassOffset + 360) % 360
90+
waitingForHeading = false
91+
}
92+
8193
// FollowingPath Returns the followingPath boolean
8294
func FollowingPath() bool {
8395
return followingPath
8496
}
8597

98+
func StopFollowingPath() {
99+
followingPath = false
100+
}
101+
86102
// CreateMap creates an empty 1x1 map (this single point will be the robots starting position.)
87103
func CreateMap() (createdMap Map) {
88104
createdMap = Map{width: 1, height: 1, robot: Robot{0, 0, 0}}
@@ -161,16 +177,14 @@ func (this *Map) addBufferToMap() {
161177
}
162178

163179
// FindLocation finds and returns the location of the robot based on the current scan information and the previous map information
164-
func (this *Map) FindLocation() (int, int, float64) {
165-
rotationAmmount := 30
166-
rotationJump := 1
180+
func (this *Map) FindLocation(areaToSearch, rotationAmmount, rotationJump int) (int, int, float64) {
167181
x, y := int(this.GetRobot().GetX()), int(this.GetRobot().GetY())
168182
var count = -999
169183
var angle = int(this.GetRobot().GetRotation())
170184
var currentRotation = int(this.GetRobot().GetRotation())
171185
for i := -rotationAmmount; i <= rotationAmmount; i += rotationJump {
172186
currentRotation = i + int(this.GetRobot().GetRotation())
173-
tempX, tempY, tempCount := this.findLocation(createMapFragment(scanBuffer, currentRotation))
187+
tempX, tempY, tempCount := this.findLocation(areaToSearch, createMapFragment(scanBuffer, currentRotation))
174188
if tempCount > count {
175189
x = tempX
176190
y = tempY
@@ -182,14 +196,22 @@ func (this *Map) FindLocation() (int, int, float64) {
182196
return x, y, float64(angle)
183197
}
184198

185-
func (this *Map) findLocation(fragment Map) (int, int, int) {
199+
func (this *Map) findLocation(areaToSearch int, fragment Map) (int, int, int) {
186200
fmt.Println("Attempting to find location...")
187201
mX, mY, mCount := int(this.GetRobot().GetX()), int(this.GetRobot().GetY()), 0
188202

189203
fmt.Println("Robots Assumed Location: (", mX, ",", mY, ")")
190204

191-
for i := 0; i < this.width; i++ {
192-
for j := 0; j < this.height; j++ {
205+
xSearch := int(this.GetRobot().GetX())
206+
ySearch := int(this.GetRobot().GetY())
207+
208+
if areaToSearch == 0 {
209+
xSearch = this.width
210+
ySearch = this.height
211+
}
212+
213+
for i := xSearch - areaToSearch; i < xSearch + areaToSearch; i++ {
214+
for j := ySearch - areaToSearch; j < ySearch + areaToSearch; j++ {
193215
if i >= 0 && j >= 0 && i < this.width && j < this.height {
194216
count, _, _ := this.probabilityAtLocation(fragment, int(i), int(j))
195217
if count != 0 {
@@ -230,9 +252,20 @@ func (this *Map) probabilityAtLocation(fragment Map, x int, y int) (int, int, in
230252
}
231253

232254
func (this *Map) TakeNextStep(lastX int, lastY int) {
255+
// If we haven't scanned in a while: do a scan and return.
256+
if distanceSinceLastScan > minimumScanDistance {
257+
distanceSinceLastScan = 0
258+
RobotDriverProtocol.Scan()
259+
return
260+
}
261+
262+
// Otherwise just continue moving
233263
if len(path) != 0 {
264+
followingPath = true
234265
robotPoint := Point{int(this.GetRobot().GetX()), int(this.GetRobot().GetY())}
235266
line, movesLeft := this.getNextMove(int(this.GetRobot().GetX()), int(this.GetRobot().GetY()), lastX, lastY, path)
267+
distanceSinceLastScan += line.getLength()
268+
fmt.Println("Current length of line: ", line.getLength())
236269

237270
fmt.Println("currentLocation: ", robotPoint)
238271
// If you are 1 move away from end point
@@ -251,7 +284,8 @@ func (this *Map) TakeNextStep(lastX int, lastY int) {
251284

252285
degree := line.getAngleFrom(robotPoint)
253286
magnitude := line.getLength()
254-
287+
offset := RobotMap.GetRobot().GetRotation()
288+
degree = (degree + int(offset)) % 360
255289
fmt.Println("[TakeNextStep]: Required Move: ", degree, " -> ", magnitude)
256290

257291
RobotDriverProtocol.Move(uint16(degree), uint32(magnitude))
@@ -269,6 +303,18 @@ func (this *Map) TakeNextStep(lastX int, lastY int) {
269303
// Used when following a path into unseen areas to prevent crashes.
270304
func (this *Map) MoveRobotAlongPath(newPath [][]bool, stopBeforePoint bool) {
271305
path = newPath
306+
lines := BitmapToVector(path)
307+
308+
for i := 0; i < len(lines); i++ {
309+
if lines[i].getLength() > minimumScanDistance {
310+
line1, line2 := lines[i].split()
311+
lines[i] = line1
312+
lines = append(lines, line2)
313+
i--
314+
}
315+
}
316+
317+
lineMap = lines
272318
followingPath = true
273319
this.TakeNextStep(-1, -1)
274320
fmt.Println("Queued a path for movement...")
@@ -286,18 +332,18 @@ func (this *Map) MoveRobotToPoint(x, y int) {
286332

287333
// Returns the next move in the path.
288334
func (this *Map) getNextMove(x, y, prevX, prevY int, path [][]bool) (line Line, possibleMove bool) {
289-
lines := BitmapToVector(path)
290-
fmt.Println("Line Map: ", lines)
291-
fmt.Println("Index: ", pathIndex, " | Size: ", len(lines))
292-
293335
robotPoint := Point{x, y}
294336
prevRobotPoint := Point{prevX, prevY}
295337

296-
for _, line := range lines {
297-
fmt.Println("Did ", line, " get past here?")
298-
fmt.Println("Previous Loc: ", prevRobotPoint)
338+
for _, line := range lineMap {
339+
if Debug {
340+
fmt.Println("Did ", line, " get past here?")
341+
fmt.Println("Previous Loc: ", prevRobotPoint)
342+
}
299343
if !line.pointOnLine(prevRobotPoint) {
300-
fmt.Println("\t", line, " contains ", robotPoint, " => ", line.pointOnLine(robotPoint))
344+
if Debug {
345+
fmt.Println("\t", line, " contains ", robotPoint, " => ", line.pointOnLine(robotPoint))
346+
}
301347
if line.pointOnLine(robotPoint) {
302348
return line, true
303349
}
@@ -477,11 +523,11 @@ func (this *Map) AddWallByLine(degree, distance float64) {
477523
fmt.Println("Adding Wall @", x, y)
478524
}
479525
this.AddWall(x, y, true)
480-
this.MarkLineAsSeen(degree, distance)
526+
this.MarkLineAsSeen(degree, distance, x, y)
481527
}
482528

483529
// MarkLineAsSeen marks anything the line passes through as "seen".
484-
func (this *Map) MarkLineAsSeen(degree, distance float64) {
530+
func (this *Map) MarkLineAsSeen(degree, distance float64, wallX, wallY int) {
485531
if Debug {
486532
fmt.Println(RobotMap)
487533
RobotMap.Print(nil)
@@ -499,31 +545,25 @@ func (this *Map) MarkLineAsSeen(degree, distance float64) {
499545
if this.seen[y][x] == 0 {
500546
this.seen[y][x] = 1
501547
}
548+
if y != wallY && x != wallX {
549+
this.floor[y][x] = false
550+
}
502551
}
503552
}
504553
}
505554

506555
// Counts the ammount of seen tiles (that are just empty space) surrounding the current tile (horizontaly and vertically)
507556
func (this *Map) getAdjacentSeenTilesCount(x, y int) (count int) {
508557
count = 0
509-
if y+1 < len(this.floor) {
510-
if this.seen[y+1][x] == 1 {
511-
count++
512-
}
513-
}
514-
if x+1 < len(this.floor[y]) {
515-
if this.seen[y][x+1] == 1 {
516-
count++
517-
}
518-
}
519-
if y-1 >= 0 {
520-
if this.seen[y-1][x] == 1 {
521-
count++
522-
}
523-
}
524-
if x-1 >= 0 {
525-
if this.seen[y][x-1] == 1 {
526-
count++
558+
for yOffset := -1; yOffset <= 1; yOffset++ {
559+
for xOffset := -1; xOffset <= 1; xOffset++ {
560+
if !(yOffset == 0 && xOffset == 0) {
561+
if y+yOffset >= 0 && x+xOffset >= 0 && y+yOffset < len(this.floor) && x+xOffset < len(this.floor[0]) {
562+
if this.seen[y+yOffset][x+xOffset] == 1 {
563+
count++
564+
}
565+
}
566+
}
527567
}
528568
}
529569
return
@@ -570,7 +610,6 @@ func (this *Map) ContinueToNextArea() {
570610
this.MoveRobotAlongPath(path, true)
571611
return
572612
}
573-
print("No valid path to node", i, "checking next node.")
574613
}
575614
if !possible {
576615
finishedMapping = true

0 commit comments

Comments
 (0)