From c78eda078266463bbf56d503f790296757dc78de Mon Sep 17 00:00:00 2001
From: Adam Sitabkhan <adam.sitabkhan@gmail.com>
Date: Sat, 11 Jan 2025 12:59:29 -0600
Subject: [PATCH] Added plotting function for rotated grids and command line
 args

---
 guided_mrmp/controllers/place_grid.py | 112 ++++++++++++++++++--------
 1 file changed, 78 insertions(+), 34 deletions(-)

diff --git a/guided_mrmp/controllers/place_grid.py b/guided_mrmp/controllers/place_grid.py
index 192ad8f..a14fbf5 100644
--- a/guided_mrmp/controllers/place_grid.py
+++ b/guided_mrmp/controllers/place_grid.py
@@ -77,15 +77,16 @@ def place_grid(robot_locations, cell_size=1, grid_shape=(5, 5), return_loss=Fals
         return origin.value, cell_centers.value, prob.value
     return origin.value, cell_centers.value
 
+
 def place_grid_with_rotation(robot_locations, cell_size=1, grid_shape=(5, 5), num_angles=18, return_angle_info=False):
     """
-        Place a grid to cover robot locations with alignment to centers. Allows rotations of the grid, but only samples 
+        Place a grid to cover robot locations with alignment to centers. 
 
         inputs:
             - robot_locations (list): locations of robots involved in conflict [[x,y], [x,y], ...]
             - cell_size (float): the width of each grid cell in continuous space
             - grid_shape (tuple): (# of rows, # of columns) of the grid
-            - num_angles (int): number of evenly spaced angles to sample between 0 and 90 degrees
+            - sample_size (int): number of evenly spaced angles to sample between 0 and pi/2 radians
         outputs:
             - grid_center (tuple): center of the grid in continuous space
             - cell_centers (list): centers of grid cells for each robot (same order as robot_locations)
@@ -99,8 +100,9 @@ def place_grid_with_rotation(robot_locations, cell_size=1, grid_shape=(5, 5), nu
     min_loss_angle = 0
     min_loss = None 
     
-    for angle in np.linspace(start=0, stop=np.pi/2, num=num_angles, endpoint=False):
-        print(angle)
+    from tqdm import tqdm
+    
+    for angle in tqdm(np.linspace(start=0, stop=np.pi/2, num=num_angles, endpoint=False), desc="Processing..."):
         rotation_matrix = np.array([[np.cos(angle), -np.sin(angle)],
                                     [np.sin(angle), np.cos(angle)]])
         
@@ -123,33 +125,13 @@ def place_grid_with_rotation(robot_locations, cell_size=1, grid_shape=(5, 5), nu
         angle_info[angle] = grid_center, cell_centers, loss
     
     if return_angle_info:
-        return angle_info[min_loss_angle][0], angle_info[min_loss_angle][1], angle_info
-    return angle_info[min_loss_angle][0], angle_info[min_loss_angle][1]
+        return *angle_info[min_loss_angle][:2], min_loss_angle, angle_info
+    return *angle_info[min_loss_angle][:2], min_loss_angle
 
-def main(rotations):
-    np.random.seed(52)
-    robot_locations = np.random.uniform(low=0, high=5, size=(5, 2))
-    cell_size = 1
-    grid_shape = (5, 5)
-    
-    import matplotlib.pyplot as plt
-    
-    if rotations:
-        grid_center, cell_centers, angle_info = place_grid_with_rotation(robot_locations, cell_size, grid_shape, num_angles=30, return_angle_info=True)
-        # angles = angle_info.keys()
-        # losses = [loss for (_, _, loss) in angle_info.values()]
-        
-        # plt.scatter(angles, losses, c='r')
-
-        # plt.show()
-    else:
-        origin, cell_centers = place_grid(robot_locations, cell_size, grid_shape)
-        print("Grid Origin (Bottom-Left Corner):", origin)
-        print(cell_centers)
 
+def plot_grid(origin, cell_size, grid_shape):
     import matplotlib.pyplot as plt
     
-    plt.figure(figsize=(4, 4))
     # Draw the grid
     for i in range(grid_shape[1] + 1):
         # Draw vertical lines
@@ -159,7 +141,58 @@ def main(rotations):
         # Draw horizontal lines
         plt.plot([origin[0], origin[0] + grid_shape[1] * cell_size], 
                     [origin[1] + i * cell_size, origin[1] + i * cell_size], 'k-')
+        
+        
+def plot_grid_with_rotation(grid_center, cell_size, grid_shape, rotation_angle):
+    rotation_matrix = np.array([[np.cos(rotation_angle), -np.sin(rotation_angle)],
+                                [np.sin(rotation_angle), np.cos(rotation_angle)]])
+    grid_center = np.array(grid_center)
+    
+    import matplotlib.pyplot as plt
+    
+    # Draw the grid
+    for i in range(grid_shape[1] + 1):
+        # Construct vertical line endpoints
+        line_points = np.array([[(-grid_shape[1] / 2 + i) * cell_size, (-grid_shape[1] / 2 + i) * cell_size],
+                                [-grid_shape[0] / 2, grid_shape[0] / 2]])
+        # Rotate vertical lines and draw
+        rotated_line_points = rotation_matrix @ line_points + grid_center[:, None]
+        plt.plot(rotated_line_points[0], rotated_line_points[1], 'k-')
+    for i in range(grid_shape[1] + 1):
+        # Construct horizontal line endpoints
+        line_points = np.array([[-grid_shape[1] / 2, grid_shape[1] / 2],
+                                [(-grid_shape[0] / 2 + i) * cell_size, (-grid_shape[0] / 2 + i) * cell_size]])
+        # Rotate horizontal lines and draw
+        rotated_line_points = rotation_matrix @ line_points + grid_center[:, None]
+        plt.plot(rotated_line_points[0], rotated_line_points[1], 'k-')
 
+
+def main(allow_rotations, num_robots, num_angles, seed):
+    if seed is not None:
+        np.random.seed(seed)
+    
+    robot_locations = np.random.uniform(low=0, high=5, size=(num_robots, 2))
+    cell_size = 1
+    grid_shape = (5, 5)
+    
+    import matplotlib.pyplot as plt
+    
+    plt.figure(figsize=(6, 6))
+    
+    if allow_rotations:
+        grid_center, cell_centers, rotation_angle = place_grid_with_rotation(robot_locations, cell_size, grid_shape, num_angles=num_angles)
+        print("Grid Center:", grid_center)
+        # angles = angle_info.keys()
+        # losses = [loss for (_, _, loss) in angle_info.values()]
+        # plt.scatter(angles, losses, c='r')
+        
+        plot_grid_with_rotation(grid_center, cell_size, grid_shape, rotation_angle)
+    else:
+        origin, cell_centers = place_grid(robot_locations, cell_size, grid_shape)
+        print("Grid Origin (Bottom-Left Corner):", origin)
+        
+        plot_grid(origin, cell_size, grid_shape)
+    
     # Plot robot locations
     robot_locations = np.array(robot_locations)
     plt.scatter(robot_locations[:, 0], robot_locations[:, 1], c='r', label='Robot Locations')
@@ -167,10 +200,6 @@ def main(rotations):
     # Plot cell centers
     cell_centers = np.array(cell_centers)
     plt.scatter(cell_centers[:, 0], cell_centers[:, 1], c='b', label='Cell Centers')
-    for (cx, cy) in cell_centers:
-        x = [cx - cell_size/2, cx + cell_size/2, cx + cell_size/2, cx - cell_size/2, cx - cell_size/2]
-        y = [cy - cell_size/2, cy - cell_size/2, cy + cell_size/2, cy + cell_size/2, cy - cell_size/2]
-        plt.plot(x, y, c='r')
     
     plt.legend(loc='upper left')
 
@@ -181,10 +210,25 @@ if __name__ == "__main__":
     
     parser = argparse.ArgumentParser()
     parser.add_argument(
-        "--rotations", 
+        "--allow_rotations", 
         type=bool, 
-        required=True
+        default=False
+    )
+    parser.add_argument(
+        "--num_robots", 
+        type=int, 
+        default=2
+    )
+    parser.add_argument(
+        "--num_angles", 
+        type=int, 
+        default=18
+    )
+    parser.add_argument(
+        "--seed", 
+        type=int, 
+        default=None
     )
     args = parser.parse_args()
 
-    main(args.rotations)
\ No newline at end of file
+    main(args.allow_rotations, args.num_robots, args.num_angles, args.seed)
\ No newline at end of file
-- 
GitLab