Spaces:
Running
on
Zero
Running
on
Zero
derektan
Init new app to handle planning. Fresh import from 27fe831777c12b25e504dd14e5b661742bdecce6 from VLM-Search
4f09ecf
####################################################################### | |
# Name: sensor.py | |
# | |
# - Computes sensor related checks (e.g. collision, utility etc) | |
####################################################################### | |
import sys | |
if sys.modules['TRAINING']: | |
from parameter import * | |
else: | |
from test_parameter import * | |
import math | |
import numpy as np | |
import copy | |
def collision_check(x0, y0, x1, y1, ground_truth, robot_belief): | |
x0 = x0.round() | |
y0 = y0.round() | |
x1 = x1.round() | |
y1 = y1.round() | |
dx, dy = abs(x1 - x0), abs(y1 - y0) | |
x, y = x0, y0 | |
error = dx - dy | |
x_inc = 1 if x1 > x0 else -1 | |
y_inc = 1 if y1 > y0 else -1 | |
dx *= 2 | |
dy *= 2 | |
collision_flag = 0 | |
max_collision = 10 | |
while 0 <= x < ground_truth.shape[1] and 0 <= y < ground_truth.shape[0]: | |
k = ground_truth.item(y, x) | |
if k == 1 and collision_flag < max_collision: | |
collision_flag += 1 | |
if collision_flag >= max_collision: | |
break | |
if k !=1 and collision_flag > 0: | |
break | |
if x == x1 and y == y1: | |
break | |
robot_belief.itemset((y, x), k) | |
if error > 0: | |
x += x_inc | |
error -= dy | |
else: | |
y += y_inc | |
error += dx | |
return robot_belief | |
def sensor_work(robot_position, sensor_range, robot_belief, ground_truth, sensor_model=SENSOR_MODEL): | |
x0 = robot_position[0] | |
y0 = robot_position[1] | |
rng_x = 0.5 * (ground_truth.shape[1] / NUM_COORDS_WIDTH) | |
rng_y = 0.5 * (ground_truth.shape[0] / NUM_COORDS_HEIGHT) | |
if sensor_model == "rectangular": # TODO: add collision check | |
max_x = min(x0 + int(math.ceil(rng_x)), ground_truth.shape[1]) | |
min_x = max(x0 - int(math.ceil(rng_x)), 0) | |
max_y = min(y0 + int(math.ceil(rng_y)), ground_truth.shape[0]) | |
min_y = max(y0 - int(math.ceil(rng_y)), 0) | |
robot_belief[min_y:max_y, min_x:max_x] = ground_truth[min_y:max_y, min_x:max_x] | |
else: | |
sensor_angle_inc = 0.5 / 180 * np.pi | |
sensor_angle = 0 | |
while sensor_angle < 2 * np.pi: | |
x1 = x0 + np.cos(sensor_angle) * sensor_range | |
y1 = y0 + np.sin(sensor_angle) * sensor_range | |
robot_belief = collision_check(x0, y0, x1, y1, ground_truth, robot_belief) | |
sensor_angle += sensor_angle_inc | |
return robot_belief | |
def unexplored_area_check(x0, y0, x1, y1, current_belief): | |
x0 = x0.round() | |
y0 = y0.round() | |
x1 = x1.round() | |
y1 = y1.round() | |
dx, dy = abs(x1 - x0), abs(y1 - y0) | |
x, y = x0, y0 | |
error = dx - dy | |
x_inc = 1 if x1 > x0 else -1 | |
y_inc = 1 if y1 > y0 else -1 | |
dx *= 2 | |
dy *= 2 | |
while 0 <= x < current_belief.shape[1] and 0 <= y < current_belief.shape[0]: | |
k = current_belief.item(y, x) | |
if x == x1 and y == y1: | |
break | |
if k == 1: | |
break | |
if k == 127: | |
current_belief.itemset((y, x), 0) | |
break | |
if error > 0: | |
x += x_inc | |
error -= dy | |
else: | |
y += y_inc | |
error += dx | |
return current_belief | |
def calculate_utility(waypoint_position, sensor_range, robot_belief): | |
sensor_angle_inc = 5 / 180 * np.pi | |
sensor_angle = 0 | |
x0 = waypoint_position[0] | |
y0 = waypoint_position[1] | |
current_belief = copy.deepcopy(robot_belief) | |
while sensor_angle < 2 * np.pi: | |
x1 = x0 + np.cos(sensor_angle) * sensor_range | |
y1 = y0 + np.sin(sensor_angle) * sensor_range | |
current_belief = unexplored_area_check(x0, y0, x1, y1, current_belief) | |
sensor_angle += sensor_angle_inc | |
utility = np.sum(robot_belief == 127) - np.sum(current_belief == 127) | |
return utility | |