From a26b2214614adcc774f6ea86f92a967af93a15ac Mon Sep 17 00:00:00 2001 From: "oceanpdoshi@g.ucla.edu" <oceanpdoshi@.ucla.edu> Date: Fri, 19 Apr 2019 12:49:29 -0700 Subject: [PATCH] Refactored some more elements of the code to be interchangable. Currently debugging communications of request/response messages. --- .../simulated_dataset_manager.py | 111 +++++++----------- 1 file changed, 42 insertions(+), 69 deletions(-) diff --git a/CoLo-AT/dataset_manager/simulated_dataset_manager.py b/CoLo-AT/dataset_manager/simulated_dataset_manager.py index b8ddf90..8656977 100644 --- a/CoLo-AT/dataset_manager/simulated_dataset_manager.py +++ b/CoLo-AT/dataset_manager/simulated_dataset_manager.py @@ -1,4 +1,4 @@ -from math import pi, sqrt +from math import pi, sqrt, atan2 import numpy as np import IPython @@ -29,6 +29,10 @@ class SimulatedDataSetManager: self.robot_labels = robot_labels self.num_robots = len(robot_labels) + # Internal time "counter" + self.time_idx = 0 + self.delta_t = 1 + # angular width of robots's vision with respect to the x_axis (radians) self.robot_vision = robot_vision @@ -40,16 +44,17 @@ class SimulatedDataSetManager: self.boundary = boundary # All robots begin moving at t = 0s - self.start_time = 0 + self.start_time = 20.0 self.end_time = self.start_time + self.duration self.start_moving_times = [0 for label in robot_labels] # landmarks = {landmark ID: [x,y]} + # NOTE - landmark IDs must be bigger than 5. self.landmark_map = landmarks # starting_states = {robot label: [time, x_pos, y_pos, orientation], ... } # TODO - Update this to be user-specified on how to initialize robot locations. - self.starting_states = {label : [0, i, i, 0] for i,label in enumerate(robot_labels)} + self.starting_states = {label : [self.start_time, i, i, 0] for i,label in enumerate(robot_labels)} # in the simulation all the times for all the measurements are the same. self.time_arr = {'odometry': [[] for i in range(self.num_robots)], 'measurement': [[] for i in range(self.num_robots)], @@ -57,7 +62,7 @@ class SimulatedDataSetManager: for data_type in self.time_arr: for i in range(self.num_robots): - self.time_arr[data_type][i] = np.arange(duration) + self.time_arr[data_type][i] = np.arange(self.start_time, self.end_time+1) # Measurement Data Format @@ -98,80 +103,57 @@ class SimulatedDataSetManager: ''' self.groundtruth_data = [ [] for i in range(self.num_robots)] - - # TODO - convert to dynamic generation, just generate ground truth data def simulate_dataset(self): - # Generate ground truth data # NOTE - FOR NOW THIS WILL JUST MOVE ROBOTS IN A STRAIGHT LINE UNTIL THEY REACH THE BOUNDARY - THEN THEY WILL BE STATIONARY for i, label in enumerate(self.robot_labels, 0): # append starting state self.groundtruth_data[i].append({'time' : self.starting_states[label][0], 'x_pos': self.starting_states[label][1], 'y_pos': self.starting_states[label][2], 'orientation' : self.starting_states[label][3]}) - for time in range(1, len(self.time_arr['groundtruth'][i])): - curr_x = self.groundtruth_data[i][time-1]['x_pos'] - curr_y = self.groundtruth_data[i][time-1]['y_pos'] - curr_orientation = self.groundtruth_data[i][time-1]['orientation'] + for j in range(1, len(self.time_arr['groundtruth'][i])): + curr_x = self.groundtruth_data[i][j-1]['x_pos'] + curr_y = self.groundtruth_data[i][j-1]['y_pos'] + curr_orientation = self.groundtruth_data[i][j-1]['orientation'] next_x = curr_x next_y = curr_y next_orientation = curr_orientation - next_time = time + 1 if (self.within_map([curr_x + 1, curr_y + 1])): next_x = curr_x + 1 next_y = curr_y - self.groundtruth_data[i].append({'time' : next_time, 'x_pos': next_x, 'y_pos': next_y, 'orientation': next_orientation}) + self.groundtruth_data[i].append({'time' : self.time_arr['groundtruth'][i][j], 'x_pos': next_x, 'y_pos': next_y, 'orientation': next_orientation}) # NOTE - modify incorporation of noise # Generate Odometery Data for i, label in enumerate(self.robot_labels, 0): # Initial robot state - self.odometry_data[i].append({'time': 0, 'velocity' : 0, 'angular velocity' : 0, 'orientation' : self.groundtruth_data[i][0]['orientation'], + self.odometry_data[i].append({'time': self.start_time, 'velocity' : 0, 'angular velocity' : 0, 'orientation' : self.groundtruth_data[i][0]['orientation'], 'delta_t' : 0}) - for time in range(1, len(self.time_arr['odometry'][i])): - # NOTE - delta_t is currently hard coded to 1 as we only have ground truth data on each individual tick, this can be changed later on - delta_t = 1 - loc1 = [self.groundtruth_data[i][time-1]['x_pos'], self.groundtruth_data[i][time-1]['y_pos']] - loc2 = [self.groundtruth_data[i][time]['x_pos'], self.groundtruth_data[i][time]['y_pos']] - velocity = self.calc_distance(loc1, loc2)/delta_t + np.random.normal(loc=0.0,scale=self.odometry_noise) + for j in range(1, len(self.time_arr['odometry'][i])): + # NOTE - delta_t is currently hard coded to 1 + loc1 = [self.groundtruth_data[i][j-1]['x_pos'], self.groundtruth_data[i][j-1]['y_pos']] + loc2 = [self.groundtruth_data[i][j]['x_pos'], self.groundtruth_data[i][j]['y_pos']] + velocity = self.calc_distance(loc1, loc2)/self.delta_t + np.random.normal(loc=0.0,scale=self.odometry_noise) - theta_1 = self.groundtruth_data[i][time-1]['orientation'] - theta_2 = self.groundtruth_data[i][time]['orientation'] - angular_velocity = (theta_2-theta_1)/delta_t + np.random.normal(loc=0.0,scale=0.1) + theta_1 = self.groundtruth_data[i][j-1]['orientation'] + theta_2 = self.groundtruth_data[i][j]['orientation'] + angular_velocity = (theta_2-theta_1)/self.delta_t + np.random.normal(loc=0.0,scale=self.odometry_noise) - self.odometry_data[i].append({'time': time, 'velocity' : velocity, 'angular velocity' : angular_velocity, - 'orientation' : self.groundtruth_data[i][time]['orientation'], 'delta_t' : delta_t}) + self.odometry_data[i].append({'time': self.time_arr['odometry'][i][j], 'velocity' : velocity, 'angular velocity' : angular_velocity, + 'orientation' : self.groundtruth_data[i][j]['orientation'], 'delta_t' : self.delta_t}) - # Generate Measurment Data + # Generate Measurement Data for i, label in enumerate(self.robot_labels, 0): - for time in range(0, len(self.time_arr['measurement'][i])): + for j in range(0, len(self.time_arr['measurement'][i])): for landmarkID, landmark_loc in self.landmark_map.items(): - robot_loc_x = self.groundtruth_data[i][time]['x_pos'] - robot_loc_y = self.groundtruth_data[i][time]['y_pos'] + robot_loc_x = self.groundtruth_data[i][j]['x_pos'] + robot_loc_y = self.groundtruth_data[i][j]['y_pos'] robot_loc = [robot_loc_x, robot_loc_y] if (self.within_vision(2*pi, robot_loc, landmark_loc)): - - measurment_range = self.calc_distance(robot_loc, landmark_loc) + np.random.normal(loc=0.0,scale=self.measurement_noise) - # NOTE - arctan returns between [-pi/2, pi/2] - bearing = 0 - # Same point - if (landmark_loc[1] == robot_loc[1] and landmark_loc[0] == robot_loc[0]): - # TODO - robots are NOT supposed to collide with landmarks - bearing = 0 - # either + or - pi/2 (delta_x = 0) - elif (landmark_loc[0] == robot_loc[0]): - if (landmark_loc[1] < robot_loc[1]): - bearing = -1*pi/2 - else: - bearing = pi/2 - else: - bearing = np.arctan((landmark_loc[1]-robot_loc[1])/(landmark_loc[0]-robot_loc[0])) + np.random.normal(loc=0.0,scale=0.1) - # We only want bearings between [0, 2pi] - if (bearing < 0): - bearing += 2*pi - - self.measurement_data[i].append({'time':time, 'subject_ID': landmarkID, 'measurment_range':measurment_range, 'bearing':bearing}) + measurement_range = self.calc_distance(robot_loc, landmark_loc) + np.random.normal(loc=0.0,scale=self.measurement_noise) + bearing = atan2((landmark_loc[1]-robot_loc[1]), (landmark_loc[0]-robot_loc[0])) + np.random.normal(loc=0.0,scale=0.1) + self.measurement_data[i].append({'time': self.time_arr['measurement'][i][j], 'subject_ID': landmarkID, 'measurment_range':measurement_range, 'bearing':bearing}) self.dataset_data = {'odometry': self.odometry_data, 'measurement': self.measurement_data, 'groundtruth': self.groundtruth_data} return self.start_time, self.starting_states, self.dataset_data, self.time_arr @@ -201,24 +183,26 @@ class SimulatedDataSetManager: gt = self.groundtruth_data[robot_index][gt_time] return gt + def updateTime(self): + self.time_idx += 1 def respond(self, req, current_time, need_specific_time = False): valid_respond, message, req_type, robot_idx, time_idx = self.get_dataline(req, current_time) - current_time += 1 + # current_time == self.time_arr[req_type][robot_idx][time_idx] if (valid_respond): - req.set_time(time_idx) + req.set_time(current_time) req.set_message(message) req.set_robot_idx(robot_idx) req.set_type(req_type) - print(req.get_type()) - return valid_respond, current_time, req + print(req.get_message()) + + return valid_respond, current_time+self.delta_t, req # Alternates odometry and measurement updates - # TODO - dynamic generation def get_dataline(self, req, current_time): message = req.get_message() @@ -236,12 +220,12 @@ class SimulatedDataSetManager: self.next_request = 'odometry' else: req_type = req.get_type() - time_arr = self.get_time_arr(req_type) - robot_idx = np.argmin(time_arr) + robot_idx = np.argmin(self.time_arr[req_type]) message['robot_index'] = robot_idx - time_idx = current_time + + time_idx = np.where(self.time_arr[req_type][robot_idx] == current_time)[0][0] if self.dataset_data[req_type][robot_idx][time_idx]['time'] > self.end_time or time_idx == -1: valid_dataline = False else: @@ -250,17 +234,6 @@ class SimulatedDataSetManager: message['groundtruth'] = self.groundtruth_data[robot_idx][time_idx] return valid_dataline, message, req_type, robot_idx, time_idx - # Helper Functions - - def generate_groundtruth(): - return True - - def generate_odometry(): - return True - - def generate_measurement(): - return True - # Check if a given loc [x,y] is within map def within_map(self, loc): center_point = [0,0] -- GitLab