Exemple #1
0
    def compute_thrust(self, vessel, t):
        v = np.array(vessel.flight(vessel.orbit.body.reference_frame).velocity)
        if vessel.flight().surface_altitude > 20000:
            dt = 5
        else:
            dt = 1
        if self.traj.compute_coasting(self.conn.space_center,
                                      vessel,
                                      t=t,
                                      dt=dt,
                                      tgt_alt=self.tgt_alt + self.aim_height):
            # Find impact position on surface
            t0, r0, v0, a0 = self.traj.path[0]
            tT, rT, vF, aT = self.traj.path[-1]

            # Compute target position in the future - all in rotating reference frame now
            rTgt, rotm = utils.target_position_and_rotation(
                vessel, self.tgt_lat, self.tgt_lng,
                self.tgt_alt + self.aim_height,
                vessel.orbit.body.reference_frame)

            r = np.linalg.norm(rT)
            dE = rT - rTgt
            # convert to local surface reference frame

            # Convert from non_rotating co-ords into surface/target relative co-ords
            F = -dE
            print "Boostback prediction dist:", np.linalg.norm(dE)
            throttle = np.linalg.norm(F) * self.throttle_Kp

            # compute thrust
            att = np.array(
                vessel.flight(vessel.orbit.body.reference_frame).direction)
            ddot = F.dot(att) / np.linalg.norm(F)
            print "ddot:", ddot
            if ddot < 0.9:
                throttle = 0.01  # enough to steer

            if np.linalg.norm(F) < self.deadzone:
                if not self.in_deadzone:
                    print "Prediction within deadzone of %dm" % self.deadzone
                    self.in_deadzone = True
                throttle = 0
                # Steer retrograde
                F = -v
            else:
                self.in_deadzone = False

            return throttle, F
Exemple #2
0
                           maxT_angle=args.maxT_angle,
                           maxLand_angle=args.maxLand_angle,
                           pos_P=args.pos_P,
                           vel_P=args.vel_P)
soft_landing.draw(vessel)

final_landing = FinalLanding(surface_g=vessel.orbit.body.surface_gravity,
                             cog_height=args.cog_height,
                             land_factor=args.land_factor,
                             throttle_Kp=args.throttle_Kp,
                             conn=conn)

# returns position in given reference frame
# and rotation matrix that converts from vessel.orbit.body.reference_frame to
# X(Up), Y(North), Z(East) in local target co-ordinates
pos_tgt, rotm = utils.target_position_and_rotation(vessel, tgt_lat, tgt_lng,
                                                   tgt_alt)
irotm = np.transpose(rotm)
t0 = conn.space_center.ut
t_draw = 0
latt = None
##################################### MAIN LOOP ########################################
while True:
    # Main instrument/guidance data
    t = conn.space_center.ut - t0
    r = np.array(vessel.position(vessel.orbit.body.reference_frame))
    v = np.array(vessel.flight(vessel.orbit.body.reference_frame).velocity)
    att = np.array(vessel.flight(vessel.orbit.body.reference_frame).direction)
    h = vessel.flight(vessel.surface_velocity_reference_frame).surface_altitude
    if vessel.available_thrust > 0:
        twr = vessel.available_thrust / vessel.mass
    else:
Exemple #3
0
    def compute_soft_landing(self,
                             space_center,
                             vessel,
                             tgt_lat,
                             tgt_lng,
                             tgt_alt,
                             dt=1,
                             compute_t=0.5,
                             t0=0,
                             logfile=None,
                             maxT_angle=90,
                             maxLand_angle=15,
                             min_throttle=0.05,
                             max_throttle=0.9):
        """Compute trajectory for soft-landing phase"""

        r = np.array(vessel.position(vessel.orbit.body.reference_frame))
        v = np.array(vessel.flight(vessel.orbit.body.reference_frame).velocity)

        rTgt, rotm = utils.target_position_and_rotation(
            vessel, tgt_lat, tgt_lng, tgt_alt)

        # vars
        twr = vessel.max_thrust / vessel.mass
        t_per_N = 5
        max_N = 8
        r2 = rotm.dot(r - rTgt)
        v2 = rotm.dot(v)
        att = rotm.dot(
            np.array(
                vessel.flight(vessel.orbit.body.reference_frame).direction))
        g = np.array([-vessel.orbit.body.surface_gravity, 0., 0.])
        results = {}

        # progress time forward to compute_t to start trajectory in future, allowing for real time to compute it
        r2 = r2 + v2 * compute_t + 0.5 * g * compute_t * compute_t
        v2 = v2 + g * compute_t

        # Function solver called from golden_search()
        def f(T):
            num_thrust = int(T / t_per_N)
            num_thrust = max(3, min(num_thrust, max_N))
            print "Evaluating f(T=%.3f)" % T, "num_thrust=", num_thrust
            fuel, accels = gfold.solve(r2,
                                       v2,
                                       att,
                                       T=T,
                                       N=num_thrust,
                                       g=g,
                                       max_thrust=twr * max_throttle,
                                       min_thrust=twr * min_throttle,
                                       maxT_angle=maxT_angle,
                                       maxLand_angle=maxLand_angle,
                                       dt=T / 100.0,
                                       min_height=40)
            if accels != None:
                results[fuel] = (T, accels)
                print "Saving fuel=", fuel, "T=", T, "Accels=", len(accels)
            print "Solving for T=%.2f N=%d fuel=%.1f" % (T, num_thrust, fuel)
            return fuel

        # Convert co-ords to target surface reference frame
        min_T = utils.golden_search(f, 1, 120, tol=0.1)
        # Find minimum T from results (as above might return an infeasible region)

        if results:
            fuels = sorted(list(results.keys()))
            for f in fuels:
                print "Fuel:", f, "T:", results[f][0]
            min_fuel = fuels[0]
            min_T = results[min_fuel][0]
            accels = results[min_fuel][1]

            self.path = utils.compute_trajectory(r2,
                                                 v2,
                                                 accels,
                                                 min_T,
                                                 g,
                                                 dt=dt,
                                                 t0=t0 + compute_t)

            # make sure trajectory ends at (0,0,0) - bit of a cheat
            #self.path = utils.correct_trajectory(self.path)

            print "logfile", logfile
            if logfile:
                self.save(logfile)

            # Convert co-ords back to rotating reference frame - for drawing
            self.path = self.convert_local_to_rotating_reference_frame(
                rTgt, rotm)
            return True

        self.path = []
        return False
Exemple #4
0
    def compute_thrust(self, vessel, t):
        h = vessel.flight().surface_altitude
        r = np.array(vessel.position(vessel.orbit.body.reference_frame))
        v = np.array(vessel.flight(vessel.orbit.body.reference_frame).velocity)
        twr = vessel.max_thrust / vessel.mass

        # Get target altitude between tgt_alt and tgt_alt+aim_height aimed current_alt-aim_below
        aim_height = utils.clamp(
            vessel.flight().surface_altitude - self.aim_below, self.tgt_alt,
            self.tgt_alt + self.aim_height)
        # Compute target position in the future - all in rotating reference frame now
        rTgt, rotm = utils.target_position_and_rotation(
            vessel, self.tgt_lat, self.tgt_lng, aim_height,
            vessel.orbit.body.reference_frame)

        if h > 20000:
            dt = 5
        else:
            dt = 1
        # Compute trajectory in rotating co-ords
        if self.traj.compute_coasting(self.conn.space_center,
                                      vessel,
                                      t=t,
                                      dt=dt,
                                      tgt_alt=aim_height):
            # Find impact position on surface
            t0, r0, v0, a0 = self.traj.path[0]
            tT, rT, vF, aT = self.traj.path[-1]

            dE = rT - rTgt
            print "Coasting predict err:", dE, "aim alt:", aim_height

            vst = dE / np.linalg.norm(dE)  # prediction direction
            mag = min(1, np.linalg.norm(dE) * 0.006)  # 200m = maximum steering
            F = -v / np.linalg.norm(v) + 0.3 * vst * mag

            # Use thrust to stop horizontal motion?
            # convert into horizontal co-ords
            dF = r - rTgt
            hdF = rotm.dot(dF)
            hdF[0] = 0
            hv = rotm.dot(v)
            hv[0] = 0
            #print "Horizontal distance:",hdF[1],"N",hdF[2],"E (m)"
            #print "Horizontal speed:",np.linalg.norm(hv)
            dhd = np.linalg.norm(hdF + hv) - np.linalg.norm(hdF)
            #print "Change in hor. distance:",dhd
            # Find point of closest approach (ignoring altitude)
            rClose, u = utils.closest_point_on_line(hdF, hv, np.zeros(3))
            if u < 0:  # behind current position, so current position is closest
                rClose = hdF
            #print "Closest approach dist:",np.linalg.norm(rClose),"at:",u
            d = np.linalg.norm(rClose)  # dist to closest point
            dz = rClose[2] - hdF[2]  # dist in z direction
            print "Dist to closest point (East):", dz

            throttle = 0
            if np.linalg.norm(hv) > 10 and np.linalg.norm(
                    hdF) < 20000 and h > 10000:
                factor = 0.0015
                Kp = 0.5
                v_wanted = twr * factor * dz
                err = hv[2] - v_wanted
                print "wanted:", v_wanted, "actual:", hv[2]
                throttle = err * Kp  # last component to hover
                print

            return throttle, F

        return 0, -v
Exemple #5
0
    def compute_thrust(self, vessel, t):
        """Follow the computed trajectory - if there is one"""

        # Set Force/direction based on closest trajectory point in speed/position
        r = np.array(vessel.position(vessel.orbit.body.reference_frame))
        v = np.array(vessel.flight(vessel.orbit.body.reference_frame).velocity)
        g = np.array([-vessel.orbit.body.surface_gravity, 0.,
                      0.])  # in local target ref frame
        twr = vessel.max_thrust / vessel.mass

        # Convert to local co-ords for target,rotm converting from rotating ref to local, with X=up
        # r_Tgt is target position in rotating ref frame
        r_Tgt, rotm = utils.target_position_and_rotation(
            vessel, self.tgt_lat, self.tgt_lng, self.tgt_alt)
        irotm = np.transpose(rotm)

        # Gains of 1.0, 0.0 means find closest position only (ignore velocity)
        dr, dv, F = self.traj.closest_to_trajectory(r, v, 1.0, 1.0)

        if dr == None:
            return 0, None  # not on trajectory

        F2 = rotm.dot(F)

        r2 = rotm.dot(r - r_Tgt)
        v2 = rotm.dot(v)
        dr2 = rotm.dot(dr - r_Tgt)
        dv2 = rotm.dot(dv)

        self.PID_x.setPoint(dr2[0])
        self.PID_y.setPoint(dr2[1])
        self.PID_z.setPoint(dr2[2])
        self.PID_vx.setPoint(dv2[0])
        self.PID_vy.setPoint(dv2[1])
        self.PID_vz.setPoint(dv2[2])

        # Update PID controllers
        px = self.PID_x.update(r2[0])
        py = self.PID_y.update(r2[1])
        pz = self.PID_z.update(r2[2])
        pvx = self.PID_vx.update(v2[0])
        pvy = self.PID_vy.update(v2[1])
        pvz = self.PID_vz.update(v2[2])

        #print "px:",px,"py:",py,"pz:",pz
        #print "pvx:",pvx,"pvy:",pvy,"pvz:",pvz

        print >> self.fpid, "%.2f\t%.2f\t%.2f\t%.2f\t%.2f\t%.2f\t%.2f\t%.2f\t%.2f\t%.2f\t%.2f\t%.2f\t%.2f\t%.2f\t%.2f\t%.2f\t%.2f\t%.2f\t%.2f" % (
            t, r2[0], r2[1], r2[2], v2[0], v2[1], v2[2], dr2[0], dr2[1],
            dr2[2], dv2[0], dv2[1], dv2[2], px, py, pz, pvx, pvy, pvz)
        self.fpid.flush()

        # Correct force vector
        F2 = F2 + np.array([px, py, pz]) + np.array([pvx, pvy, pvz])
        #F2 = F2 + np.array([px,py,pz]) # aim only for position

        # Don't thrust down
        if F2[0] < 0.1:
            throttle = self.steer_throttle
            F2 = np.array([0.1, F2[1], F2[2]])
        throttle = np.linalg.norm(F2) / twr

        F = irotm.dot(F2)

        # Shut-off throttle if pointing away from desired direction
        att = np.array(
            vessel.flight(vessel.orbit.body.reference_frame).direction)
        ddot = np.dot(F / np.linalg.norm(F), att / np.linalg.norm(att))
        if (ddot < math.cos(math.radians(70))):
            throttle = self.steer_throttle  # enough to steer

        return throttle, F