diff --git a/guided_mrmp/controllers/mpc.py b/guided_mrmp/controllers/mpc.py
index e9d5cb9c94269a111056984bc1edd7ed6e55a075..dc548e38a5d4e2abae64b75be7467cb463731416 100644
--- a/guided_mrmp/controllers/mpc.py
+++ b/guided_mrmp/controllers/mpc.py
@@ -3,7 +3,7 @@ import casadi as ca
 from guided_mrmp.controllers.optimizer import Optimizer
 
 class MPC:
-    def __init__(self, model, T, DT, state_cost, final_state_cost, input_cost, input_rate_cost, settings):
+    def __init__(self, model, T, DT, settings):
         """
 
         Args:
@@ -21,6 +21,11 @@ class MPC:
         self.robot_model = model
         self.dt = DT
 
+        state_cost = settings['model_predictive_controller']['Q']  # state error cost
+        final_state_cost = settings['model_predictive_controller']['Qf']  # state final error cost
+        input_cost = settings['model_predictive_controller']['R']  # input cost
+        input_rate_cost = settings['model_predictive_controller']['P']  # input rate of change cost
+
         # how far we can look into the future divided by our dt 
         # is the number of control intervals
         self.control_horizon = int(T / DT) 
@@ -35,10 +40,10 @@ class MPC:
         self.R = np.diag(input_cost)
         self.P = np.diag(input_rate_cost)
 
-        self.acceptable_tol = settings['acceptable_tol']
-        self.acceptable_iter = settings['acceptable_iter']
-        self.print_level = settings['print_level']
-        self.print_time = settings['print_time']
+        self.acceptable_tol = settings['model_predictive_controller']['acceptable_tol']
+        self.acceptable_iter = settings['model_predictive_controller']['acceptable_iter']
+        self.print_level = settings['model_predictive_controller']['print_level']
+        self.print_time = settings['model_predictive_controller']['print_time']
 
     def setup_mpc_problem(self, initial_state, target, prev_cmd, A, B, C):
 
diff --git a/guided_mrmp/controllers/multi_mpc.py b/guided_mrmp/controllers/multi_mpc.py
index 2295bb548c2a9ee08c5b8f98892eac0ce6dff073..abd7c0cb623a5aff1ef36d6e33942dd48a9f22f1 100644
--- a/guided_mrmp/controllers/multi_mpc.py
+++ b/guided_mrmp/controllers/multi_mpc.py
@@ -131,6 +131,7 @@ class MultiMPC:
                         d = ca.sqrt(d)
                         dist_to_other_robots += self.apply_quadratic_barrier(6*self.robot_radius, d-self.robot_radius*2, 1)
 
+        dist_to_other_robots = 0
         # obstacle collision cost
         obstacle_cost = 0
         for k in range(self.control_horizon):
diff --git a/guided_mrmp/controllers/multi_path_tracking.py b/guided_mrmp/controllers/multi_path_tracking.py
index bd34177359834391b5653a0dd47c26489f34a294..c4bfe47d9c32cc1ba227e2b2735e117a7cedc8e0 100644
--- a/guided_mrmp/controllers/multi_path_tracking.py
+++ b/guided_mrmp/controllers/multi_path_tracking.py
@@ -3,6 +3,7 @@ import matplotlib.pyplot as plt
 
 from guided_mrmp.controllers.utils import compute_path_from_wp, get_ref_trajectory
 from guided_mrmp.controllers.multi_mpc import MultiMPC
+from guided_mrmp.controllers.mpc import MPC
 
 class MultiPathTracker:
     def __init__(self, env, initial_positions, dynamics, target_v, T, DT, waypoints, settings, lib_2x3, lib_3x3, lib_2x5):
@@ -45,7 +46,10 @@ class MultiPathTracker:
 
         self.settings = settings
 
-        self.mpc = MultiMPC(self.num_robots, dynamics, T, DT, settings, env.circle_obs)
+
+        self.coupled_mpc = MultiMPC(self.num_robots, dynamics, T, DT, settings, env.circle_obs)
+
+        self.mpc = MPC(dynamics, T, DT, settings)
 
         self.circle_obs = env.circle_obs
         self.rect_obs = env.rect_obs
@@ -143,7 +147,7 @@ class MultiPathTracker:
         # dynamycs w.r.t robot frame
         # curr_state = np.array([0, 0, self.state[2], 0])
         curr_states = np.zeros((self.num_robots, 3))
-        x_mpc, u_mpc = self.mpc.step(
+        x_mpc, u_mpc = self.coupled_mpc.step(
             curr_states,
             targets,
             self.control
diff --git a/guided_mrmp/controllers/multi_path_tracking_db.py b/guided_mrmp/controllers/multi_path_tracking_db.py
index 1230b0fe4862eb949d9fb36d38274c4b46670967..b7723a244eecafbcb91d9dc12612463f7518e02b 100644
--- a/guided_mrmp/controllers/multi_path_tracking_db.py
+++ b/guided_mrmp/controllers/multi_path_tracking_db.py
@@ -182,7 +182,6 @@ class MultiPathTrackerDB(MultiPathTracker):
 
         return {'X': initial_guess_state, 'U': initial_guess_control, 'T': initial_guess_T}
 
-    
     def get_obstacle_map(self, grid_origin, grid_size, radius):
         """
         Create a map of the environment with obstacles
@@ -406,6 +405,10 @@ class MultiPathTrackerDB(MultiPathTracker):
         return False
     
     def advance(self, state, show_plots=False):
+
+        u_next = [[] for _ in range(self.num_robots)]
+        x_next = [[] for _ in range(self.num_robots)]
+
         # 1. Get the reference trajectory for each robot
         targets = []
         for i in range(self.num_robots):
@@ -421,6 +424,18 @@ class MultiPathTrackerDB(MultiPathTracker):
             targets.append(ref)
         self.trajs = targets
 
+        curr_state = np.array([0,0,0])
+        for i in range(self.num_robots):
+            
+            x_mpc, u_mpc = self.mpc.step(
+                curr_state,
+                targets[i],
+                self.control[i]
+            )
+
+            u_next[i] = [u_mpc[0, 0], u_mpc[1, 0]]
+            x_next[i] = x_mpc
+
         # 2. Check if the targets of any two robots overlap
         all_conflicts = []
         for i in range(self.num_robots):
@@ -443,92 +458,126 @@ class MultiPathTrackerDB(MultiPathTracker):
             for i in (c):
                 robot_positions.append(state[i][:2])
 
+            # get the largest x and y difference between the robots in conflict
+            x_diff = max([abs(robot_positions[i][0] - robot_positions[j][0]) for i in c for j in c])
+            y_diff = max([abs(robot_positions[i][1] - robot_positions[j][1]) for i in c for j in c])
+            diff = max(x_diff, y_diff)
+
+            
             # Put down a local grid
             self.cell_size = self.radius*3
             self.grid_size = 5
-            grid_origin, centers = place_grid(robot_positions, cell_size=self.radius*3)
-            grid_obstacle_map = self.get_obstacle_map(grid_origin, self.grid_size, self.radius) 
-            if show_plots: self.draw_grid(state, grid_origin, self.cell_size, 5)
 
-            # Solve a discrete version of the problem 
-            # Find a subproblem and solve it
-            grid_solution = self.get_discrete_solution(state, c, all_conflicts, grid_obstacle_map, grid_origin)
+            if diff < 4*self.cell_size:
+                grid_origin, centers = place_grid(robot_positions, cell_size=self.radius*3)
+                grid_obstacle_map = self.get_obstacle_map(grid_origin, self.grid_size, self.radius) 
+                if show_plots: self.draw_grid(state, grid_origin, self.cell_size, 5)
+
+                # Solve a discrete version of the problem 
+                # Find a subproblem and solve it
+                grid_solution = self.get_discrete_solution(state, c, all_conflicts, grid_obstacle_map, grid_origin)
 
             
 
-            if grid_solution:
-                # if we found a grid solution, we can use it to reroute the robots
-                initial_guess = self.get_initial_guess(state, grid_solution, len(c), 20, .5)
-                initial_guess_state = initial_guess['X']
+                if grid_solution:
+                    print(f"Grid Solution: {grid_solution}")
+                    # if we found a grid solution, we can use it to reroute the robots
+                    initial_guess = self.get_initial_guess(state, grid_solution, len(c), 20, 0.0)
+                    initial_guess_state = initial_guess['X']
 
-                if show_plots: self.draw_grid_solution(initial_guess_state, state, grid_origin, len(c))
+                    if show_plots: self.draw_grid_solution(initial_guess_state, state, grid_origin, len(c))
+                    
+                    # for each robot in conflict, reroute its reference trajectory to match the grid solution
+                    import copy
+                    old_paths = copy.deepcopy(self.paths)
+
+                    # self.paths = []
+                    # for i in range(num_robots_in_conflict):
+                    for i, robot_idx in enumerate(c):
+                        new_ref = initial_guess_state[robot_idx*3:robot_idx*3+3, :]
+
+                        # plan from the last point of the ref path to the robot's goal
+                        # plan an RRT path from the current state to the goal
+
+                        x_start = (new_ref[:, -1][0], new_ref[:, -1][1])
+                        x_goal = (old_paths[i][:, -1][0], old_paths[i][:, -1][1])
+
+                        rrtstar2 = RRTStar(self.env,x_start, x_goal, 0.5, 0.05, 500, r=2.0)
+                        rrtstarpath2,tree = rrtstar2.run()
+                        rrtstarpath2 = list(reversed(rrtstarpath2))
+                        xs = new_ref[0, :].tolist()
+                        ys = new_ref[1, :].tolist()
+
+                        for node in rrtstarpath2:
+                            xs.append(node[0])
+                            ys.append(node[1])
+
+                        wp = [xs,ys]
+
+                        # Path from waypoint interpolation
+                        self.paths[i] = compute_path_from_wp(wp[0], wp[1], 0.05)
+
+                    targets = []
+                    for i in range(self.num_robots):
+                        ref, visited_guide_points = get_ref_trajectory(np.array(state[i]), 
+                                                            np.array(self.paths[i]), 
+                                                            self.target_v, 
+                                                            self.T, 
+                                                            self.DT, 
+                                                            [])
                 
-                # for each robot in conflict, reroute its reference trajectory to match the grid solution
-                num_robots_in_conflict = len(c)
-                import copy
-                old_paths = copy.deepcopy(self.paths)
-
-                # self.paths = []
-                # for i in range(num_robots_in_conflict):
-                for i, robot_idx in enumerate(c):
-                    new_ref = initial_guess_state[i*3:i*3+3, :]
+                        self.visited_points_on_guide_paths[i] = visited_guide_points
+                        
+                        targets.append(ref)
+                    self.trajs = targets
+
+                    curr_state = np.array([0,0,0])
+                    for i in range(self.num_robots):
+                        
+                        x_mpc, u_mpc = self.mpc.step(
+                            curr_state,
+                            targets[i],
+                            self.control[i]
+                        )
+
+                        u_next[i] = [u_mpc[0, 0], u_mpc[1, 0]]
+                        x_next[i] = x_mpc
+
+                if grid_solution is None:
+                    # if there isnt a grid solution, the most likely scenario is that the robots 
+                    # are not close enough together to place down a subproblem
+                    # in this case, we just allow the robts to continue on their paths and resolve 
+                    # the conflict later
+                    print("No grid solution found, proceeding with the current paths")
+                    # TODO: This should call coupled MPC to resolve the conflict
+
+                    # dynamycs w.r.t robot frame
+                    curr_states = np.zeros((self.num_robots, 3))
+                    x_mpc, u_mpc = self.coupled_mpc.step(
+                        curr_states,
+                        targets,
+                        self.control
+                    )
+
+                    for i in c:
+                        u_next[i] = [u_mpc[i*2, 0], u_mpc[i*2+1, 0]]
+                        x_next[i] = x_mpc[i]
+
+            else:
+                print("The robots are too far apart to place a grid")
+                print("Proceeding with the current paths")
 
-                    # plan from the last point of the ref path to the robot's goal
-                    # plan an RRT path from the current state to the goal
 
-                    x_start = (new_ref[:, -1][0], new_ref[:, -1][1])
-                    x_goal = (old_paths[i][:, -1][0], old_paths[i][:, -1][1])
 
-                    rrtstar2 = RRTStar(self.env,x_start, x_goal, 0.5, 0.05, 500, r=2.0)
-                    rrtstarpath2,tree = rrtstar2.run()
-                    rrtstarpath2 = list(reversed(rrtstarpath2))
-                    xs = new_ref[0, :].tolist()
-                    ys = new_ref[1, :].tolist()
-
-                    for node in rrtstarpath2:
-                        xs.append(node[0])
-                        ys.append(node[1])
-
-                    wp = [xs,ys]
-
-                    # Path from waypoint interpolation
-                    self.paths[i] = compute_path_from_wp(wp[0], wp[1], 0.05)
-
-                targets = []
-                for i in range(self.num_robots):
-                    ref, visited_guide_points = get_ref_trajectory(np.array(state[i]), 
-                                                           np.array(self.paths[i]), 
-                                                           self.target_v, 
-                                                           self.T, 
-                                                           self.DT, 
-                                                           self.visited_points_on_guide_paths[i])
-            
-                    self.visited_points_on_guide_paths[i] = visited_guide_points
-                    
-                    targets.append(ref)
-                self.trajs = targets
-
-            if grid_solution is None:
-                # if there isnt a grid solution, the most likely scenario is that the robots 
-                # are not close enough together to place down a subproblem
-                # in this case, we just allow the robts to continue on their paths and resolve 
-                # the conflict later
-                print("No grid solution found, proceeding with the current paths")
-
-        # dynamycs w.r.t robot frame
-        curr_states = np.zeros((self.num_robots, 3))
-        x_mpc, u_mpc = self.mpc.step(
-            curr_states,
-            targets,
-            self.control
-        )
         
         # only the first one is used to advance the simulation
-        self.control = []
-        for i in range(self.num_robots):
-            self.control.append([u_mpc[i*2, 0], u_mpc[i*2+1, 0]])
+        # self.control = []
+        # for i in range(self.num_robots):
+        #     self.control.append([u_mpc[i*2, 0], u_mpc[i*2+1, 0]])
+
+        self.control = u_next
 
-        return x_mpc, self.control
+        return x_next, u_next
 
 
 def main():