Универсальный робот
Автор
Map initialization
In [ ]:
room = gen_room_rand( 25, 20 )
start_x, start_y, dir_x, dir_y = gen_start_point(room)
# As in the original script, we do not check that every empty square can be reached
# This can be done with the standard breadth-first search: as long as there are unvisited squares we can run
# the search again (but on walls instead of empty squares) to find the shortest path through them
Out[0]:
Robot initialization
In [ ]:
# Creates a sensor function, which senses "point" in coordinates relative to robot position and direction
function rel_point_sense(point::CartesianIndex)
return function(pos, dir, room)
p = pos + dir*point[1] + point[2]*rotate(dir,90)
if all(1 .<= Tuple(p) .<= size(room))
return [p]
else
return []
end
end
end
robot = Robot()
# Initialize sensors: can see straight forward and diagonally forward
push!(robot.sensors, rel_point_sense(forward))
push!(robot.sensors, rel_point_sense(forward+right))
push!(robot.sensors, rel_point_sense(forward+left))
# Initialize move actions: can move in all 4 directions, rotates in the direction it moved
push!(robot.moves, (pos,dir) -> (pos+dir,dir))
push!(robot.moves, (pos,dir) -> (pos+rotate(dir,90),rotate(dir,90)))
push!(robot.moves, (pos,dir) -> (pos+rotate(dir,-90),rotate(dir,-90)))
push!(robot.moves, (pos,dir) -> (pos-dir,-dir))
# Initialize memory
init_memory!(robot, start_x, start_y, dir_x, dir_y, size(room)[1], size(room)[2])
# Set goal: explore (with sensors) the whole room
replace!(robot.map, unknown => goal_check)
heatmap(-replace(robot.map', goal_check => 3), yflip=:true, aspect_ratio=:equal, leg=:false, title="Initial map")
Out[0]:
In [ ]:
run_robot!(robot, room)
Out[0]:
As before, visited and studied maps are not equal.
If you want the robot to visit the whole map, you could replace all room empty squares with goals and remove stopping condition in the run_robot function, so that it continues moving until all goals are reached.
In [ ]:
plot( heatmap( -replace(robot.map', goal_check => 3), title="Studied map", aspect_ratio=:equal, leg=:false, size = 30*[size(room,1),size(room,2)]), heatmap( robot.visited', title="Visited map", aspect_ratio=:equal, leg=:false, size = 30*[size(room,1),size(room,2)]))
Out[0]:
