def min_time_traj_avoid_obs(self,
                                p0,
                                v0,
                                pf,
                                vf,
                                obstacles=None,
                                p_puck=None):
        """Minimum time trajectory while avoiding obstacles."""
        x0 = np.array(np.concatenate((p0, v0), axis=0))
        xf = np.concatenate((pf, vf), axis=0)

        N = 20
        prog = DirectCollocation(self.sys_c,
                                 self.sys_c.CreateDefaultContext(),
                                 N,
                                 minimum_timestep=self.params.dt,
                                 maximum_timestep=self.params.dt)

        # Initial and final state
        prog.AddBoundingBoxConstraint(x0, x0, prog.initial_state())
        prog.AddQuadraticErrorCost(Q=np.eye(4),
                                   x_desired=xf,
                                   vars=prog.final_state())
        u = prog.input()
        prog.AddRunningCost(0.1 * u.dot(u))

        prog.AddEqualTimeIntervalsConstraints()

        ## Input saturation
        self.add_input_limits(prog)

        # Arena constraints
        self.add_arena_limits(prog)

        prog.AddFinalCost(prog.time())

        # Add non-linear constraints - will solve with SNOPT
        # Avoid other players
        if obstacles != None:
            for p_obs in obstacles:
                distance = prog.state()[0:2] - p_obs
                prog.AddConstraintToAllKnotPoints(
                    distance.dot(distance) >= (2.0 *
                                               self.params.player_radius)**2)

        # avoid hitting the puck while generating a kicking trajectory
        #if not p_puck.any(None):
        #    distance = prog.state()[0:2] - p_puck
        #    prog.AddConstraintToAllKnotPoints(distance.dot(distance) >= (self.params.player_radius + self.params.puck_radius)**2)

        solver = SnoptSolver()
        result = solver.Solve(prog)
        solution_found = result.is_success()
        if not solution_found:
            print("Solution not found for intercepting_with_obs_avoidance")

        u_traj = prog.ReconstructInputTrajectory(result)
        u_values = u_traj.vector_values(u_traj.get_segment_times())
        return solution_found, u_values
Exemple #2
0
    def compute_control(self, x0_p1, x0_p2, xf_p1, xf_p2, obstacles):
        """This is basically the single-agent MPC algorithm"""
        prog = DirectCollocation(self.mpc_params.sys_two_players_c, self.mpc_params.sys_two_players_c.CreateDefaultContext(), self.mpc_params.N+1,
                    minimum_timestep=self.mpc_params.minT, maximum_timestep=self.mpc_params.maxT)
        x0 = np.concatenate((x0_p1, x0_p2), axis=0)
        prog.AddBoundingBoxConstraint(x0, x0, prog.initial_state())
        x_des = np.concatenate((xf_p1, xf_p2))
        Q = np.zeros((8,8))
        Q[0:4,0:4] = self.mpc_params.Omega_N_max
        Q[4:8,4:8] = self.mpc_params.Omega_N_max
        prog.AddQuadraticErrorCost(Q, x_desired=x_des, vars=prog.final_state())

        prog.AddEqualTimeIntervalsConstraints()

        for obs_pos in obstacles: # both players should avoid the other players
            for n in range(self.mpc_params.N):
                x = prog.state()
                prog.AddConstraintToAllKnotPoints((x[0:2]-obs_pos).dot(x[0:2]-obs_pos) >= (2.0*self.sim_params.player_radius)**2)
                prog.AddConstraintToAllKnotPoints((x[4:6]-obs_pos).dot(x[4:6]-obs_pos) >= (2.0*self.sim_params.player_radius)**2)

        # players should avoid each other
        prog.AddConstraintToAllKnotPoints((x[0:2]-x[4:6]).dot(x[0:2]-x[4:6]) >= (2.0*self.sim_params.player_radius)**2)
        
        # input constraints
        for i in range(4):
            prog.AddConstraintToAllKnotPoints(prog.input()[i] <=  self.sim_params.input_limit)
            prog.AddConstraintToAllKnotPoints(prog.input()[i] >= -self.sim_params.input_limit)

        r = self.sim_params.player_radius
        prog.AddConstraintToAllKnotPoints(prog.state()[0] + r <=  self.sim_params.arena_limits_x / 2.0)
        prog.AddConstraintToAllKnotPoints(prog.state()[0] - r >= -self.sim_params.arena_limits_x / 2.0)
        prog.AddConstraintToAllKnotPoints(prog.state()[1] + r <=  self.sim_params.arena_limits_y / 2.0)
        prog.AddConstraintToAllKnotPoints(prog.state()[1] - r >= -self.sim_params.arena_limits_y / 2.0)
        prog.AddConstraintToAllKnotPoints(prog.state()[4] + r <=  self.sim_params.arena_limits_x / 2.0)
        prog.AddConstraintToAllKnotPoints(prog.state()[4] - r >= -self.sim_params.arena_limits_x / 2.0)
        prog.AddConstraintToAllKnotPoints(prog.state()[5] + r <=  self.sim_params.arena_limits_y / 2.0)
        prog.AddConstraintToAllKnotPoints(prog.state()[5] - r >= -self.sim_params.arena_limits_y / 2.0)

        prog.AddFinalCost(prog.time())

        if not self.prev_u is None and not self.prev_x is None:
            prog.SetInitialTrajectory(traj_init_u=self.prev_u, traj_init_x=self.prev_x)

        solver = SnoptSolver()
        result = solver.Solve(prog)

        u_traj = prog.ReconstructInputTrajectory(result)
        x_traj = prog.ReconstructStateTrajectory(result)

        self.prev_u = u_traj
        self.prev_x = x_traj

        u_vals = u_traj.vector_values(u_traj.get_segment_times())
        x_vals = x_traj.vector_values(x_traj.get_segment_times())

        return True, u_vals[0:2,0], u_vals[2:4,0]
Exemple #3
0
    def compute_control(self, x_des, sim_state, team_name, player_id):
        prog = DirectCollocation(self.mpc_params.sys,
                                 self.mpc_params.sys.CreateDefaultContext(),
                                 self.mpc_params.N,
                                 minimum_timestep=self.mpc_params.minT,
                                 maximum_timestep=self.mpc_params.maxT)

        pos0 = sim_state.get_player_pos(team_name, player_id)
        vel0 = sim_state.get_player_vel(team_name, player_id)
        x0 = np.concatenate((pos0, vel0), axis=0)
        prog.AddBoundingBoxConstraint(x0, x0, prog.initial_state())
        prog.AddQuadraticErrorCost(Q=self.mpc_params.Omega_N_max,
                                   x_desired=x_des,
                                   vars=prog.final_state())

        obstacle_positions = self.get_obstacle_positions(
            sim_state, team_name, player_id)
        for obs_pos in obstacle_positions:
            for n in range(self.mpc_params.N):
                x = prog.state()
                prog.AddConstraintToAllKnotPoints(
                    (x[0:2] - obs_pos).dot(x[0:2] - obs_pos) >= (
                        2.0 * self.sim_params.player_radius)**2)

        prog.AddEqualTimeIntervalsConstraints()

        self.add_input_limits(prog)
        self.add_arena_limits(prog)

        prog.AddFinalCost(prog.time())

        if not self.prev_u is None and not self.prev_x is None:
            prog.SetInitialTrajectory(traj_init_u=self.prev_u,
                                      traj_init_x=self.prev_x)

        solver = SnoptSolver()
        result = solver.Solve(prog)

        u_traj = prog.ReconstructInputTrajectory(result)
        x_traj = prog.ReconstructStateTrajectory(result)

        u_vals = u_traj.vector_values(u_traj.get_segment_times())

        self.prev_u = u_traj
        self.prev_x = x_traj

        return u_vals[:, 0]
    def min_time_traj_dir_col(self, p0, v0, pf, vf):
        """generate minimum time trajectory while avoiding obs"""
        N = 15
        minT = self.params.dt / N
        maxT = 5.0 / N
        x0 = np.concatenate((p0, v0), axis=0)
        xf = np.concatenate((pf, vf), axis=0)

        prog = DirectCollocation(self.sys_c, self.sys_c.CreateDefaultContext(), num_time_samples=N,
                                 minimum_timestep=minT,
                                 maximum_timestep=maxT)
        prog.AddBoundingBoxConstraint(x0, x0, prog.initial_state())
        prog.AddEqualTimeIntervalsConstraints()
        self.add_input_limits(prog)
        self.add_arena_limits(prog)

        prog.AddQuadraticErrorCost(Q=10.0*np.eye(4), x_desired=xf, vars=prog.final_state())
        prog.AddFinalCost(prog.time())

        solver = SnoptSolver()
        result = solver.Solve(prog)
        if not result.is_success():
            print("Minimum time trajectory: optimization failed")
            return False, np.zeros((2, 1))

        # subsample trajectory accordingly
        u_trajectory = prog.ReconstructInputTrajectory(result)
        duration = u_trajectory.end_time() - u_trajectory.start_time()
        if duration > self.params.dt:
            times = np.linspace(u_trajectory.start_time(), u_trajectory.end_time(), (u_trajectory.end_time() - u_trajectory.start_time()) / self.params.dt )
        else:
            times = np.array([0])

        u_values = np.empty((2, len(times)))
        for i, t in enumerate(times):
            u_values[:, i] = u_trajectory.value(t).flatten()

        return result.is_success(), u_values
    def min_time_bounce_kick_traj_dir_col(self, p0, v0, p0_puck, v0_puck, v_puck_desired):
        """DO NOT USE. NOT WORKING.
        Minimum time trajectory + bounce kick off the wall."""
        N = 15
        minT = self.params.dt / N
        maxT = 5.0 / N
        x0 = np.concatenate((p0, v0), axis=0)
        prog = DirectCollocation(self.sys_c, self.sys_c.CreateDefaultContext(), num_time_samples=N,
                                 minimum_timestep=minT,
                                 maximum_timestep=maxT)
        prog.AddBoundingBoxConstraint(x0, x0, prog.initial_state())
        prog.AddEqualTimeIntervalsConstraints()
        self.add_final_state_constraint_elastic_collision(prog, p0_puck, v0_puck, v_puck_desired)
        self.add_input_limits(prog)
        self.add_arena_limits(prog)

        # prog.AddQuadraticErrorCost(Q=10.0*np.eye(4), x_desired=xf, vars=prog.final_state())
        pf = p0_puck - self.get_normalized_vector(v_puck_desired)*(self.params.puck_radius + self.params.player_radius)
        prog.AddQuadraticErrorCost(Q=10.0*np.eye(2), x_desired=pf, vars=prog.final_state()[:2])

        prog.AddFinalCost(prog.time())

        solver = SnoptSolver()
        result = solver.Solve(prog)
        if not result.is_success():
            print("Minimum time trajectory: optimization failed")
            return False, np.zeros((2, 1))

        u_trajectory = prog.ReconstructInputTrajectory(result)
        times = np.linspace(u_trajectory.start_time(), u_trajectory.end_time(), (u_trajectory.end_time() - u_trajectory.start_time()) / self.params.dt )

        u_values = np.empty((2, len(times)))
        for i, t in enumerate(times):
            u_values[:, i] = u_trajectory.value(t).flatten()

        return result.is_success(), u_values
    def get_initial_guess(self, x_p1, p_goal, p_puck, obstacles):
        """This is basically the single-agent MPC algorithm"""
        hit_dir = p_goal - p_puck
        hit_dir = 6.0 * hit_dir / np.linalg.norm(hit_dir)
        x_des = np.array([p_puck[0], p_puck[1], hit_dir[0], hit_dir[1]])
        #x_des = np.array([1.0, 1.0, 0, 0])
        print("x_des: {}, {}".format(x_des[0], x_des[1]))
        print("x_des shape", x_des.shape)
        print("zeros.shape", np.zeros(4).shape)
        print("p_player", x_p1[0:2])
        print("p_puck {}, {}".format(p_puck[0], p_puck[1]))
        print("p_goal", p_goal)
        prog = DirectCollocation(self.mpc_params.sys_c,
                                 self.mpc_params.sys_c.CreateDefaultContext(),
                                 self.mpc_params.N + 1,
                                 minimum_timestep=self.mpc_params.minT,
                                 maximum_timestep=self.mpc_params.maxT)

        prog.AddBoundingBoxConstraint(x_p1, x_p1, prog.initial_state())
        prog.AddQuadraticErrorCost(Q=self.mpc_params.Omega_N_max,
                                   x_desired=x_des,
                                   vars=prog.final_state())

        prog.AddEqualTimeIntervalsConstraints()

        # generate trajectory non in collision with puck
        #for n in range(self.mpc_params.N):
        #    x = prog.state()
        #    eps = 0.1
        #    obs_pos = p_puck[0:2]
        #    prog.AddConstraintToAllKnotPoints((x[0:2]-obs_pos).dot(x[0:2]-obs_pos) >= (self.sim_params.player_radius + self.sim_params.puck_radius - eps)**2)

        for obs_pos in obstacles:
            for n in range(self.mpc_params.N):
                x = prog.state()
                prog.AddConstraintToAllKnotPoints(
                    (x[0:2] - obs_pos).dot(x[0:2] - obs_pos) >= (
                        2.0 * self.sim_params.player_radius)**2)

        prog.AddConstraintToAllKnotPoints(
            prog.input()[0] <= self.sim_params.input_limit)
        prog.AddConstraintToAllKnotPoints(
            prog.input()[0] >= -self.sim_params.input_limit)
        prog.AddConstraintToAllKnotPoints(
            prog.input()[1] <= self.sim_params.input_limit)
        prog.AddConstraintToAllKnotPoints(
            prog.input()[1] >= -self.sim_params.input_limit)

        r = self.sim_params.player_radius
        prog.AddConstraintToAllKnotPoints(
            prog.state()[0] + r <= self.sim_params.arena_limits_x / 2.0)
        prog.AddConstraintToAllKnotPoints(
            prog.state()[0] - r >= -self.sim_params.arena_limits_x / 2.0)
        prog.AddConstraintToAllKnotPoints(
            prog.state()[1] + r <= self.sim_params.arena_limits_y / 2.0)
        prog.AddConstraintToAllKnotPoints(
            prog.state()[1] - r >= -self.sim_params.arena_limits_y / 2.0)

        prog.AddFinalCost(prog.time())

        if not self.prev_u is None and not self.prev_x is None:
            prog.SetInitialTrajectory(traj_init_u=self.prev_u,
                                      traj_init_x=self.prev_x)

        solver = SnoptSolver()
        result = solver.Solve(prog)

        u_traj = prog.ReconstructInputTrajectory(result)
        x_traj = prog.ReconstructStateTrajectory(result)

        self.prev_u = u_traj
        self.prev_x = x_traj

        u_vals = u_traj.vector_values(u_traj.get_segment_times())
        x_vals = x_traj.vector_values(x_traj.get_segment_times())
        print(u_vals)
        print(u_vals[:, 0])
        return u_vals[:, 0]