Exemplo n.º 1
0
def inputToPWM():
    
    # initialize node
    rospy.init_node('inputToPWM', anonymous=True)
    
    global pubname , newECU , subname, move , still_moving
    newECU = ECU() 
    newECU.motor = 1500
    newECU.servo = 1550
    move = False
    still_moving = False
    #print("1")
    #print(move)
    # topic subscriptions / publications
    pubname = rospy.Publisher('ecu_pwm',ECU, queue_size = 2)
    rospy.Subscriber('turtle1/cmd_vel', Twist, start_callback)
    subname = rospy.Subscriber('uOpt', Input, callback_function)
    rospy.Subscriber('moving', Moving, moving_callback_function)
    # set node rate
    loop_rate   = 40
    ts          = 1.0 / loop_rate
    rate        = rospy.Rate(loop_rate)
    t0          = time.time()
     
    rospy.spin()
Exemplo n.º 2
0
def inputToPWM():

    # initialize node
    rospy.init_node('inputToPWM', anonymous=True)

    global pubname, newECU, subname, move, still_moving
    newECU = ECU()
    newECU.motor = 1500
    newECU.servo = 1550
    move = False
    still_moving = False
    #print("1")
    #print(move)
    # topic subscriptions / publications
    pubname = rospy.Publisher('ecu_pwm', ECU, queue_size=2)
    rospy.Subscriber('turtle1/cmd_vel', Twist, start_callback)
    rospy.Subscriber('encoder', Encoder, enc_callback)  # Line Added
    subname = rospy.Subscriber('uOpt', Input, callback_function)
    rospy.Subscriber('moving', Moving, moving_callback_function)
    # set node rate
    loop_rate = 40
    ts = 1.0 / loop_rate
    rate = rospy.Rate(loop_rate)
    t0 = time.time()

    while not rospy.is_shutdown():
        # calculate acceleration from PID controller.
        motor_pwm = PID_control.acc_calculate(v_ref, v_meas) + motor_pwm_offset
        # publish control command
        ecu_pub.publish(ECU(motor_pwm, servo_pwm))
        # wait
        rate.sleep()
Exemplo n.º 3
0
def inputToPWM():
    global motor_pwm, servo_pwm, motor_pwm_offset, servo_pwm_offset
    global v_ref, v_meas

    # initialize node
    rospy.init_node('inputToPWM', anonymous=True)

    global pubname, newECU, subname, move, still_moving
    newECU = ECU()
    newECU.motor = 1500
    newECU.servo = 1550
    move = False
    still_moving = False
    #print("1")
    #print(move)
    # topic subscriptions / publications
    pubname = rospy.Publisher('ecu_pwm', ECU, queue_size=2)
    rospy.Subscriber('turtle1/cmd_vel', Twist, start_callback)
    subname = rospy.Subscriber('uOpt', Input, callback_function)
    rospy.Subscriber('moving', Moving, moving_callback_function)
    rospy.Subscriber('hold_previous_turn', Bool, hold_turn_function)
    rospy.Subscriber('encoder', Encoder, enc_callback)
    # set node rate
    loop_rate = 40
    ts = 1.0 / loop_rate
    rate = rospy.Rate(loop_rate)
    t0 = time.time()

    # Initialize the PID controller
    longitudinal_control = PID(kp=30, ki=3, kd=0)
    maxspeed = 1620
    minspeed = 1400

    while not rospy.is_shutdown():
        try:
            # acceleration calculated from PID controller
            motor_pwm = longitudinal_control.acc_calculate(
                v_ref, v_meas) + motor_pwm_offset
            if (motor_pwm < minspeed):
                motor_pwm = minspeed
            elif (motor_pwm > maxspeed):
                motor_pwm = maxspeed

            if (move == False):
                motor_pwm = 1500
                servo_pwm = 1550

            # publish information
            pubname.publish(ECU(motor_pwm, servo_pwm))

            # wait
            rate.sleep()
        except:
            pass
Exemplo n.º 4
0
def move(current):
    msg = ECU()
    msg.motor = 1500
    msg.servo = 1500
    if 'a' in current:
        msg.servo -= 300
    elif 'd' in current:
        msg.servo += 300

    if 'w' in current:
        msg.motor += 100
    elif 's' in current:
        msg.motor -= 200

    return msg
Exemplo n.º 5
0
def image_node():
    global error
    error = 0

    param_names = [
        'lowerY', 'upperY', 'display_image', 'display_processed_image',
        'debug_info', 'publish_processed_image'
    ]
    params = {}
    for param in param_names:
        params[param] = rospy.get_param(param)
    print(params)

    rospy.init_node('Test_Imager')
    img_pub = rospy.Publisher('/processed_image', Image, queue_size=1)
    #params['img_pub'] = img_pub
    rospy.Subscriber('/image_raw/compressed', CompressedImage, image_process,
                     params)
    pub = rospy.Publisher('ecu_pwm', ECU, queue_size=10)
    rate = rospy.Rate(10)

    K = 400
    Ki = 20
    integral = 0
    while not rospy.is_shutdown():
        msg = ECU()

        #   if params['debug_info']:
        #      print(error)
        msg.motor = 1590
        msg.servo = 1500 + K * error  # Ki*integral
        pub.publish(msg)
        integral += (1 / 10) * error
        if integral > 20:
            integral = 20
        if integral < -20:
            integral = -20
        rate.sleep()
Exemplo n.º 6
0
def key_node():
    pub = rospy.Publisher('ecu_pwm', ECU, queue_size=10)
    rospy.init_node('key_node')
    rate = rospy.Rate(10)
    print('Use aswd to navigate the BARC, use q to stop')
    while not rospy.is_shutdown():
        char = getch.getch()
        msg = ECU()
        if char == 'a':
            msg.motor = 1600
            msg.servo = 1200
            pub.publish(msg)
        elif char == 'e':
            msg.motor = 1300
            msg.servo = 1800
            pub.publish(msg)
        elif char == 'q':
            msg.motor = 1300
            msg.servo = 1200
            pub.publish(msg)
        elif char == 's':
            msg.motor = 1300
            msg.servo = 1500
            pub.publish(msg)
        elif char == 'w':
            msg.motor = 1600
            msg.servo = 1500
            pub.publish(msg)
        elif char == 'd':
            msg.motor = 1600
            msg.servo = 1800
            pub.publish(msg)
        elif char == 'r':
            msg.motor = 1600
            msg.servo = 1800
            pub.publish(msg)
        elif char == 'f':
            exit(0)
Exemplo n.º 7
0
    def spin(self):
        rospy.sleep(self.init_time)
        self.start_time = rospy.get_rostime().to_sec()

        while not rospy.is_shutdown():
            t = rospy.get_rostime().to_sec() - self.start_time
            ecu_msg = ECU()

            if t >= self.max_time:
                end_msg = 'Max time of %g reached, controller shutting down...' % self.max_time
                self.task_finished = True
            elif self.state_machine.state == 'End':
                end_msg = 'Task finished, controller shutting down...'
                self.task_finished = True
            if self.task_finished:
                ecu_msg.servo = 0.0
                ecu_msg.motor = 0.0
                # Publish the final motor and steering commands
                self.ecu_pub.publish(ecu_msg)

                self.bond_log.break_bond()
                self.bond_ard.break_bond()
                rospy.loginfo(end_msg)
                rospy.signal_shutdown(end_msg)

            EV_state = self.state
            TV_pred = self.tv_state_prediction[:self.N + 1]

            EV_x, EV_y, EV_heading, EV_v = EV_state
            TV_x, TV_y, TV_heading, TV_v = TV_pred[0]

            # Generate target vehicle obstacle descriptions
            self.obs[0] = get_car_poly(TV_pred, self.TV_W, self.TV_L)

            # Get target vehicle trajectory relative to ego vehicle state
            if self.state_machine.state in [
                    'Safe-Confidence', 'Safe-Yield', 'Safe-Infeasible'
            ] or EV_v * np.cos(EV_heading) <= 0:
                rel_state = np.vstack((TV_pred[:,0]-EV_x, \
                    TV_pred[:,1]-EV_y, \
                    TV_pred[:,2]-EV_heading, \
                    np.multiply(TV_pred[:,3], np.cos(TV_pred[:,2]))-0, \
                    np.multiply(TV_pred[:,3], np.sin(TV_pred[:,2]))-EV_v*np.sin(EV_heading))).T
            else:
                rel_state = np.vstack((TV_pred[:,0]-EV_x, \
                    TV_pred[:,1]-EV_y, \
                    TV_pred[:,2]-EV_heading, \
                    np.multiply(TV_pred[:,3], np.cos(TV_pred[:,2]))-EV_v*np.cos(EV_heading), \
                    np.multiply(TV_pred[:,3], np.sin(TV_pred[:,2]))-EV_v*np.sin(EV_heading))).T

            # Scale the relative state
            # rel_state = scale_state(rel_state, rel_range, scale, bias)

            # Predict strategy to use
            scores = self.strategy_predictor.predict(
                rel_state.flatten(order='C'))
            exp_state = experimentStates(
                t=t,
                EV_curr=EV_state,
                TV_pred=TV_pred,
                score=scores,
                ref_col=[False for _ in range(self.N + 1)])
            self.state_machine.state_transition(exp_state)

            if self.state_machine.state == 'End':
                continue

            # Generate reference trajectory
            X_ref = EV_x + np.arange(self.N + 1) * self.dt * self.v_ref
            Y_ref = np.zeros(self.N + 1)
            Heading_ref = np.zeros(self.N + 1)
            V_ref = self.v_ref * np.ones(self.N + 1)
            Z_ref = np.vstack((X_ref, Y_ref, Heading_ref, V_ref)).T

            # Check for collisions along reference trajecotry
            Z_check = Z_ref
            scale_mult = 1.0
            scalings = np.maximum(np.ones(self.N + 1),
                                  scale_mult * np.abs(TV_v) / self.v_ref)
            collisions = self.constraint_generator.check_collision_points(
                Z_check[:, :2], TV_pred, scalings)

            exp_state.ref_col = collisions
            self.state_machine.state_transition(exp_state)

            # Generate hyperplane constraints
            hyp = [{
                'w':
                np.array(
                    [np.sign(Z_check[i, 0]),
                     np.sign(Z_check[i, 1]), 0, 0]),
                'b':
                0,
                'pos':
                None
            } for i in range(self.N + 1)]
            for i in range(self.N + 1):
                if collisions[i]:
                    if self.state_machine.strategy == 'Left':
                        d = np.array([0, 1])
                    elif self.state_machine.strategy == 'Right':
                        d = np.array([0, -1])
                    else:
                        d = np.array(
                            [EV_x - TV_pred[i, 0], EV_y - TV_pred[i, 1]])
                        d = d / la.norm(d)

                    hyp_xy, hyp_w, hyp_b, _ = self.constraint_generator.generate_constraint(
                        Z_check[i], TV_pred[i], d, scalings[i])

                    hyp[i] = {
                        'w': np.concatenate((hyp_w, np.zeros(2))),
                        'b': hyp_b,
                        'pos': hyp_xy
                    }

            if self.ev_state_prediction is None:
                Z_ws = Z_ref
                U_ws = np.zeros((self.N, self.n_u))
            else:
                Z_ws = np.vstack(
                    (self.ev_state_prediction[1:],
                     self.dynamics.f_dt(self.ev_state_prediction[-1],
                                        self.ev_input_prediction[-1],
                                        type='numpy')))
                U_ws = np.vstack((self.ev_input_prediction[1:],
                                  self.ev_input_prediction[-1]))

            status_ws = self.obca_controller.solve_ws(Z_ws, U_ws, self.obs)
            if status_ws['success']:
                rospy.loginfo('Warm start solved in %g s' %
                              status_ws['solve_time'])
                Z_obca, U_obca, status_sol = self.obca_controller.solve(
                    EV_state, self.last_input, Z_ref, self.obs, hyp)

            if status_ws['success'] and status_sol['success']:
                feasible = True
                collision = False
            else:
                feasible = False
                rospy.loginfo(
                    'OBCA MPC not feasible, activating safety controller')
            exp_state.feas = feasible
            self.state_machine.state_transition(exp_state)

            if self.state_machine.state in [
                    'Safe-Confidence', 'Safe-Yield', 'Safe-Infeasible'
            ]:
                self.safety_controller.set_accel_ref(EV_v * np.cos(EV_heading),
                                                     TV_v * np.cos(TV_heading))
                u_safe = self.safety_controller.solve(EV_state, TV_pred,
                                                      self.last_input)

                z_next = self.dynamics.f_dt(EV_state, u_safe, type='numpy')
                collision = check_collision_poly(z_next,
                                                 (self.EV_W, self.EV_L),
                                                 TV_pred[1],
                                                 (self.TV_W, self.TV_L))
                exp_state.actual_collision = collision

            self.state_machine.state_transition(exp_state)

            if self.state_machine.state in [
                    'Free-Driving', 'HOBCA-Unlocked', 'HOBCA-Locked'
            ]:
                Z_pred, U_pred = Z_obca, U_obca
                rospy.loginfo('Applying HOBCA control')
            elif self.state_machine.state in [
                    'Safe-Confidence', 'Safe-Yield', 'Safe-Infeasible'
            ]:
                U_pred = np.vstack((u_safe, np.zeros((self.N - 1, self.n_u))))
                Z_pred = np.vstack((EV_state, np.zeros((self.N, self.n_x))))
                for i in range(self.N):
                    Z_pred[i + 1] = self.dynamics.f_dt(Z_pred[i],
                                                       U_pred[i],
                                                       type='numpy')
                rospy.loginfo('Applying safety control')
            elif self.state_machine.state in ['Emergency-Break']:
                u_ebrake = self.emergency_controller.solve(
                    EV_state, TV_pred, self.last_input)

                U_pred = np.vstack((u_ebrake, np.zeros(
                    (self.N - 1, self.n_u))))
                Z_pred = np.vstack((EV_state, np.zeros((self.N, self.n_x))))
                for i in range(self.N):
                    Z_pred[i + 1] = self.dynamics.f_dt(Z_pred[i],
                                                       U_pred[i],
                                                       type='numpy')
                rospy.loginfo('Applying ebrake control')
            else:
                raise RuntimeError('State unrecognized')

            self.ev_state_prediction = Z_pred
            self.ev_input_prediction = U_pred

            self.last_input = U_pred[0]

            ecu_msg = ECU()
            ecu_msg.servo = U_pred[0, 0]
            ecu_msg.motor = U_pred[0, 1]
            self.ecu_pub.publish(ecu_msg)

            pred_msg = Prediction()
            pred_msg.x = Z_pred[:, 0]
            pred_msg.y = Z_pred[:, 1]
            pred_msg.psi = Z_pred[:, 2]
            pred_msg.v = Z_pred[:, 3]
            pred_msg.df = U_pred[:, 0]
            pred_msg.a = U_pred[:, 1]
            self.pred_pub.publish(pred_msg)

            score_msg = Scores()
            score_msg.scores = scores
            self.score_pub.publish(score_msg)

            fsm_state_msg = FSMState()
            fsm_state_msg.fsm_state = self.state_machine.state
            self.fsm_state_pub.publish(fsm_state_msg)

            self.rate.sleep()
Exemplo n.º 8
0
    def spin(self):
        start_time_msg = rospy.wait_for_message('/start_time',
                                                Float64,
                                                timeout=5.0)
        self.start_time = start_time_msg.data
        rospy.sleep(0.5)
        rospy.loginfo(
            '============ STRATEGY: Node START, time %g ============' %
            self.start_time)

        while not rospy.is_shutdown():
            t = rospy.get_rostime().to_sec() - self.start_time

            time_stats_msg = TimeStats()

            # Get EV state and TV prediction at current time
            EV_state = self.state
            TV_pred = self.tv_state_prediction[:self.N + 1]

            EV_x, EV_y, EV_heading, EV_v = EV_state
            TV_x, TV_y, TV_heading, TV_v = TV_pred[0]

            ecu_msg = ECU()
            ecu_msg.servo = 0.0
            ecu_msg.motor = 0.0

            if t >= self.init_time and not self.task_start:
                self.task_start = True
                rospy.loginfo(
                    '============ STRATEGY: Controler START ============')

            if t >= self.max_time and not self.task_finish:
                shutdown_msg = '============ STRATEGY: Max time of %g reached. Controler SHUTTING DOWN ============' % self.max_time
                self.task_finish = True
            elif self.state_machine.state == 'End' and not self.task_finish:
                shutdown_msg = '============ STRATEGY: Controller reached END state. Controler SHUTTING DOWN ============'
                self.task_finish = True
            elif (EV_x < self.x_boundary[0] or EV_x > self.x_boundary[1]
                  ) or (EV_y < self.y_boundary[0]
                        or EV_y > self.y_boundary[1]) and not self.task_finish:
                # Check if car has left the experiment area
                self.task_finish = True
                shutdown_msg = '============ STRATEGY: Track bounds exceeded reached. Controler SHUTTING DOWN ============'
            elif np.abs(EV_x - self.x_goal) <= 0.10 and not self.task_finish:
                self.task_finish = True
                shutdown_msg = '============ STRATEGY: Goal position reached. Controler SHUTTING DOWN ============'

            if self.task_finish:
                self.ecu_pub.publish(ecu_msg)
                self.bond_log.break_bond()
                self.bond_ard.break_bond()
                rospy.loginfo(shutdown_msg)
                rospy.signal_shutdown(shutdown_msg)

            # Generate target vehicle obstacle descriptions
            t_s = rospy.get_rostime().to_sec()
            self.obs[0] = get_car_poly(TV_pred, self.TV_W, self.TV_L)
            time_stats_msg.tv_obs_gen = rospy.get_rostime().to_sec() - t_s

            # Get target vehicle trajectory relative to ego vehicle state
            if self.state_machine.state in [
                    'Safe-Confidence', 'Safe-Yield', 'Safe-Infeasible'
            ] or EV_v * np.cos(EV_heading) <= 0:
                rel_state = np.vstack((TV_pred[:,0]-EV_x, \
                    TV_pred[:,1]-EV_y, \
                    TV_pred[:,2]-EV_heading, \
                    np.multiply(TV_pred[:,3], np.cos(TV_pred[:,2]))-0, \
                    np.multiply(TV_pred[:,3], np.sin(TV_pred[:,2]))-EV_v*np.sin(EV_heading))).T
            else:
                rel_state = np.vstack((TV_pred[:,0]-EV_x, \
                    TV_pred[:,1]-EV_y, \
                    TV_pred[:,2]-EV_heading, \
                    np.multiply(TV_pred[:,3], np.cos(TV_pred[:,2]))-EV_v*np.cos(EV_heading), \
                    np.multiply(TV_pred[:,3], np.sin(TV_pred[:,2]))-EV_v*np.sin(EV_heading))).T

            # Scale the relative state
            # rel_state = scale_state(rel_state, rel_range, scale, bias)

            # Predict strategy to use
            t_s = rospy.get_rostime().to_sec()
            scores = self.strategy_predictor.predict(
                rel_state.flatten(order='C'))
            time_stats_msg.strategy_pred = rospy.get_rostime().to_sec() - t_s

            exp_state = experimentStates(
                t=t,
                EV_curr=EV_state,
                TV_pred=TV_pred,
                score=scores,
                ref_col=[False for _ in range(self.N + 1)])
            self.state_machine.state_transition(exp_state)

            if self.state_machine.state == 'End':
                continue

            # Generate reference trajectory
            X_ref = EV_x + np.arange(self.N + 1) * self.dt * self.v_ref
            Y_ref = np.zeros(self.N + 1)
            Heading_ref = np.zeros(self.N + 1)
            V_ref = self.v_ref * np.ones(self.N + 1)
            Z_ref = np.vstack((X_ref, Y_ref, Heading_ref, V_ref)).T

            # Check for collisions along reference trajecotry
            Z_check = Z_ref
            scale_mult = 1.0
            scalings = np.maximum(np.ones(self.N + 1),
                                  scale_mult * np.abs(TV_v) / self.v_ref)

            t_s = rospy.get_rostime().to_sec()
            collisions = self.constraint_generator.check_collision_points(
                Z_check[:, :2], TV_pred, scalings)
            time_stats_msg.ref_collision_check = rospy.get_rostime().to_sec(
            ) - t_s

            exp_state.ref_col = collisions
            self.state_machine.state_transition(exp_state)

            # Generate hyperplane constraints
            t_s = rospy.get_rostime().to_sec()
            hyp = [{
                'w':
                np.array(
                    [np.sign(Z_check[i, 0]),
                     np.sign(Z_check[i, 1]), 0, 0]),
                'b':
                0,
                'pos':
                None
            } for i in range(self.N + 1)]
            for i in range(self.N + 1):
                if collisions[i]:
                    if self.state_machine.strategy == 'Left':
                        d = np.array([0, 1])
                    elif self.state_machine.strategy == 'Right':
                        d = np.array([0, -1])
                    else:
                        d = np.array(
                            [EV_x - TV_pred[i, 0], EV_y - TV_pred[i, 1]])
                        d = d / la.norm(d)

                    hyp_xy, hyp_w, hyp_b, _ = self.constraint_generator.generate_constraint(
                        Z_check[i], TV_pred[i], d, scalings[i])

                    hyp[i] = {
                        'w': np.concatenate((hyp_w, np.zeros(2))),
                        'b': hyp_b,
                        'pos': hyp_xy
                    }
            time_stats_msg.hyperplane_gen = rospy.get_rostime().to_sec() - t_s

            if self.ev_state_prediction is None:
                Z_ws = Z_ref
                U_ws = np.zeros((self.N, self.n_u))
            else:
                Z_ws = np.vstack(
                    (self.ev_state_prediction[1:],
                     self.dynamics.f_dt(self.ev_state_prediction[-1],
                                        self.ev_input_prediction[-1],
                                        type='numpy')))
                U_ws = np.vstack((self.ev_input_prediction[1:],
                                  self.ev_input_prediction[-1]))

            t_s = rospy.get_rostime().to_sec()
            status_ws = self.obca_controller.solve_ws(Z_ws, U_ws, self.obs)
            time_stats_msg.warm_start_solve = rospy.get_rostime().to_sec(
            ) - t_s
            if status_ws['success']:
                # rospy.loginfo('Warm start solved in %g s' % status_ws['solve_time'])
                t_s = rospy.get_rostime().to_sec()
                Z_obca, U_obca, status_sol = self.obca_controller.solve(
                    EV_state, self.last_input, Z_ref, self.obs, hyp)
                time_stats_msg.obca_solve = rospy.get_rostime().to_sec() - t_s
            else:
                time_stats_msg.obca_solve = -1

            if status_ws['success'] and status_sol['success']:
                feasible = True
                collision = False
            else:
                feasible = False
                rospy.loginfo(
                    '============ STRATEGY: OBCA MPC not feasible, activating safety controller ============'
                )
            exp_state.feas = feasible
            self.state_machine.state_transition(exp_state)

            if self.state_machine.state in [
                    'Safe-Confidence', 'Safe-Yield', 'Safe-Infeasible'
            ]:
                t_s = rospy.get_rostime().to_sec()
                self.safety_controller.set_accel_ref(EV_v * np.cos(EV_heading),
                                                     TV_v * np.cos(TV_heading))
                u_safe = self.safety_controller.solve(EV_state, TV_pred,
                                                      self.last_input)

                z_next = self.dynamics.f_dt(EV_state, u_safe, type='numpy')
                collision = check_collision_poly(z_next,
                                                 (self.EV_W, self.EV_L),
                                                 TV_pred[1],
                                                 (self.TV_W, self.TV_L))
                exp_state.actual_collision = collision
                time_stats_msg.safety_solve = rospy.get_rostime().to_sec(
                ) - t_s
            else:
                time_stats_msg.safety_solve = -1

            self.state_machine.state_transition(exp_state)

            if self.state_machine.state in [
                    'Free-Driving', 'HOBCA-Unlocked', 'HOBCA-Locked'
            ]:
                Z_pred, U_pred = Z_obca, U_obca
                time_stats_msg.ebrake_solve = -1
                rospy.loginfo(
                    '============ STRATEGY: Applying HOBCA control ============'
                )
            elif self.state_machine.state in [
                    'Safe-Confidence', 'Safe-Yield', 'Safe-Infeasible'
            ]:
                U_pred = np.vstack((u_safe, np.zeros((self.N - 1, self.n_u))))
                Z_pred = np.vstack((EV_state, np.zeros((self.N, self.n_x))))
                for i in range(self.N):
                    Z_pred[i + 1] = self.dynamics.f_dt(Z_pred[i],
                                                       U_pred[i],
                                                       type='numpy')
                time_stats_msg.ebrake_solve = -1
                rospy.loginfo(
                    '============ STRATEGY: Applying safety control ============'
                )
            elif self.state_machine.state in ['Emergency-Break']:
                t_s = rospy.get_rostime().to_sec()
                u_ebrake = self.emergency_controller.solve(
                    EV_state, TV_pred, self.last_input)

                U_pred = np.vstack((u_ebrake, np.zeros(
                    (self.N - 1, self.n_u))))
                Z_pred = np.vstack((EV_state, np.zeros((self.N, self.n_x))))
                for i in range(self.N):
                    Z_pred[i + 1] = self.dynamics.f_dt(Z_pred[i],
                                                       U_pred[i],
                                                       type='numpy')
                time_stats_msg.ebrake_solve = rospy.get_rostime().to_sec(
                ) - t_s
                rospy.loginfo(
                    '============ STRATEGY: Applying ebrake control ============'
                )
            else:
                ecu_msg.servo = 0.0
                ecu_msg.motor = 0.0
                self.ecu_pub.publish(ecu_msg)
                time_stats_msg.ebrake_solve = -1
                rospy.loginfo(
                    '============ STRATEGY: State unrecognized shutting down... ============'
                )

            if not self.task_start:
                rospy.loginfo(
                    '============ STRATEGY: Node up time: %g s. Controller not yet started ============'
                    % t)
                self.last_input = np.zeros(self.n_u)
            else:
                ecu_msg.servo = U_pred[0, 0]
                ecu_msg.motor = U_pred[0, 1]
                self.last_input = U_pred[0]

            # deadband = 0.01
            # if np.abs(ecu_msg.motor) <= deadband:
            #     ecu_msg.motor = 0.0
            # elif ecu_msg.motor > deadband:
            #     ecu_msg.motor = ecu_msg.motor - deadband
            # else:
            #     ecu_msg.motor = ecu_msg.motor + deadband

            self.ecu_pub.publish(ecu_msg)

            self.ev_state_prediction = Z_pred
            self.ev_input_prediction = U_pred

            pred_msg = Prediction()
            pred_msg.x = Z_pred[:, 0]
            pred_msg.y = Z_pred[:, 1]
            pred_msg.psi = Z_pred[:, 2]
            pred_msg.v = Z_pred[:, 3]
            pred_msg.df = U_pred[:, 0]
            pred_msg.a = U_pred[:, 1]
            self.pred_pub.publish(pred_msg)

            score_msg = Scores()
            score_msg.scores = scores
            self.score_pub.publish(score_msg)

            fsm_state_msg = FSMState()
            fsm_state_msg.fsm_state = self.state_machine.state
            self.fsm_state_pub.publish(fsm_state_msg)

            time_stats_msg.total = (rospy.get_rostime().to_sec() -
                                    self.start_time) - t
            self.time_stats_pub.publish(time_stats_msg)

            self.rate.sleep()
Exemplo n.º 9
0
def main():

    rospy.init_node("LPV-MPC")

    input_commands = rospy.Publisher('ecu', ECU, queue_size=1)
    pred_treajecto = rospy.Publisher('OL_predictions',
                                     prediction,
                                     queue_size=1)
    racing_info = rospy.Publisher('Racing_Info', Racing_Info, queue_size=1)

    mode = rospy.get_param("/control/mode")
    N = rospy.get_param("/control/N")

    loop_rate = 30.0
    dt = 1.0 / loop_rate
    rate = rospy.Rate(loop_rate)

    ## TODO: change this in order to be taken from the launch file
    Steering_Delay = 0  #3
    Velocity_Delay = 0

    #Steering_Delay  = int(rospy.get_param("/simulator/delay_df")/dt)

    NN_LPV_MPC = False

    #########################################################
    #########################################################

    # OFFLINE planning from LPV-MPP racing:
    planning_path = '/home/euge/GitHub/barc/workspace/src/barc/src/data/Planner_Refs'

    ## TRACK (OVAL, Racing Planner) : (30 July 19)
    CURV_Planner = sio.loadmat(planning_path +
                               '/LPV_MPC_PLANNING_1_.mat')['pCURV']
    VEL_Planner = sio.loadmat(planning_path +
                              '/LPV_MPC_PLANNING_1_.mat')['pnew_Vx']
    X_Planner = sio.loadmat(planning_path + '/LPV_MPC_PLANNING_1_.mat')['pxp']
    Y_Planner = sio.loadmat(planning_path + '/LPV_MPC_PLANNING_1_.mat')['pyp']
    PSI_Planner = sio.loadmat(planning_path +
                              '/LPV_MPC_PLANNING_1_.mat')['pyaw']

    #########################################################
    #########################################################

    # Objects initializations

    OL_predictions = prediction()
    cmd = ECU()  # Command message
    rac_info = Racing_Info()
    cmd.servo = 0.0
    cmd.motor = 0.0
    ClosedLoopData = ClosedLoopDataObj(dt, 6000, 0)  # Closed-Loop Data
    estimatorData = EstimatorData()
    map = Map()  # Map
    planning_data = PlanningData()

    first_it = 1
    NumberOfLaps = 10

    # Initialize variables for main loop
    GlobalState = np.zeros(6)
    LocalState = np.zeros(6)
    HalfTrack = 0
    LapNumber = 0
    RunController = 1
    Counter = 0
    CounterRacing = 0
    uApplied = np.array([0.0, 0.0])
    oldU = np.array([0.0, 0.0])

    RMSE_ve = np.zeros(NumberOfLaps)
    RMSE_ye = np.zeros(NumberOfLaps)
    RMSE_thetae = np.zeros(NumberOfLaps)
    RMSE_acc_y = np.zeros(NumberOfLaps)
    RMSE_matrix = np.zeros(NumberOfLaps)
    Norm_matrix = np.zeros((NumberOfLaps, 3))

    ALL_LOCAL_DATA = np.zeros(
        (2000, 8))  # [vx vy psidot thetae s ye vxaccel vyaccel udelta uaccel]
    GLOBAL_DATA = np.zeros((2000, 3))  # [x y psi]
    PREDICTED_DATA = np.zeros(
        (2000, 120))  # [vx vy psidot thetae s ye] presicted to N steps
    TLAPTIME = np.zeros((30, 1))
    ELAPSD_TIME = np.zeros((2000, 1))

    IDENT_DATA = np.zeros((2000, 5))
    Data_for_RMSE = np.zeros((2000, 4))

    References = np.array([0.0, 0.0, 0.0, 1.0])

    # Loop running at loop rate
    TimeCounter = 0
    PlannerCounter = 0
    count = True
    index = 0
    start_LapTimer = datetime.datetime.now()

    insideTrack = 1

    rospy.sleep(
        1
    )  # Soluciona los problemas de inicializacion esperando a que el estimador se inicialice bien

    vel_ref = 1
    Cf_new = 60
    SS = 0

    ###----------------------------------------------------------------###
    ### PATH TRACKING TUNING:
    ### 33 ms - 20 Hp
    Q = np.diag([100.0, 1.0, 1.0, 20.0, 0.0, 900.0])
    R = 0.5 * 0.5 * np.diag([1.0, 1.0])  # delta, a
    dR = 1.5 * 25 * np.array([1.3, 1.0])  # Input rate cost u
    Controller = PathFollowingLPV_MPC(Q, R, dR, N, vel_ref, dt, map, "OSQP",
                                      Steering_Delay, Velocity_Delay)

    # ### RACING TAJECTORY TRACKING TUNING:
    # ### 33 ms - 20 Hp
    Q = np.diag([400.0, 1.0, 1.0, 20.0, 0.0, 1100.0])
    R = 0.0 * np.diag([1.0, 1.0])  # delta, a
    dR = np.array([100.0, 45.0])  # Input rate cost u
    # dR =  np.array([ 10.0, 10.0 ])  # Input rate cost u
    Controller_TT = PathFollowingLPV_MPC(Q, R, dR, N, vel_ref, dt, map, "OSQP",
                                         Steering_Delay, Velocity_Delay)

    ### RACING TAJECTORY TRACKING TUNING:
    ### 33 ms - 20 Hp
    # Q  = np.diag([800.0, 1.0, 2.0, 10.0, 0.0, 1200.0])
    # R  = np.diag([0.0, 0.0])    # delta, a
    # # R  = np.array([146.0, 37.0])    # Input rate cost u
    # dR = np.array([20, 30.0])  # Input rate cost u
    # Controller_TT  = PathFollowingLPV_MPC(Q, R, dR, N, vel_ref, dt, map, "OSQP", Steering_Delay, Velocity_Delay)

    ###----------------------------------------------------------------###
    ###----------------------------------------------------------------###
    ###----------------------------------------------------------------###
    ###----------------------------------------------------------------###

    L_LPV_States_Prediction = np.zeros((N, 6))
    LPV_States_Prediction = np.zeros((N, 6))

    while (not rospy.is_shutdown()) and RunController == 1:
        # Read Measurements
        GlobalState[:] = estimatorData.CurrentState  # The current estimated state vector [vx vy w x y psi]
        LocalState[:] = estimatorData.CurrentState  # [vx vy w x y psi]

        if LocalState[0] < 0.01:
            LocalState[0] = 0.01

        if LapNumber == 0:  # Path tracking:
            # OUT: s, epsi, ey      IN: x, y, psi
            LocalState[4], LocalState[3], LocalState[
                5], insideTrack = map.getLocalPosition(GlobalState[3],
                                                       GlobalState[4],
                                                       GlobalState[5])

            # Check if the lap has finished
            if LocalState[4] >= 3 * map.TrackLength / 4:
                HalfTrack = 1

            new_Ref = np.array([0.0, 0.0, 0.0, 1.0])
            References = np.vstack(
                (References,
                 new_Ref))  # Simplemente se usa para guardar datos en fichero

        else:  # Trajectory tracking:

            GlobalState[5] = GlobalState[
                5] - 2 * np.pi * LapNumber  ## BODY FRAME ERROR COMPUTATION:

            GlobalState[5] = wrap(GlobalState[5])

            PSI_Planner[0, PlannerCounter] = wrap(PSI_Planner[0,
                                                              PlannerCounter])

            # Offline planning data:
            # OUT: s, ex, ey, epsi
            # LocalState[4], Xerror, LocalState[3], LocalState[5] = Body_Frame_Errors(GlobalState[3],
            #      GlobalState[4], GlobalState[5], X_Planner[0,PlannerCounter], Y_Planner[0,PlannerCounter],
            #      PSI_Planner[0,PlannerCounter], SS, LocalState[0], LocalState[1], CURV_Planner[0, PlannerCounter], dt )

            # print "Desired yaw = ", PSI_Planner[0,PlannerCounter], " and Real yaw = ", GlobalState[5]

            # Online planning data:
            new_Ref = np.array([
                planning_data.x_d[0], planning_data.y_d[0],
                planning_data.psi_d[0], planning_data.vx_d[0]
            ])
            References = np.vstack((References, np.transpose(new_Ref)))

            max_window = 0

            if index <= max_window:
                if index == 0:
                    X_REF_vector = planning_data.x_d[0:N + max_window]
                    Y_REF_vector = planning_data.y_d[0:N + max_window]
                    YAW_REF_vector = planning_data.psi_d[0:N + max_window]
                    VEL_REF_vector = planning_data.vx_d[0:N + max_window]
                    CURV_REF_vector = planning_data.curv_d[0:N + max_window]

                x_ref = X_REF_vector[index:index + N]
                y_ref = Y_REF_vector[index:index + N]
                yaw_ref = YAW_REF_vector[index:index + N]
                vel_ref = VEL_REF_vector[index:index + N]
                curv_ref = CURV_REF_vector[index:index + N]
                index += 1
            else:
                index = 0

            # OUT: s, ex, ey, epsi
            LocalState[4], Xerror, LocalState[5], LocalState[
                3] = Body_Frame_Errors(GlobalState[3], GlobalState[4],
                                       GlobalState[5], x_ref[0], y_ref[0],
                                       yaw_ref[0], SS, LocalState[0],
                                       LocalState[1], curv_ref[0], dt)

            SS = LocalState[4]

        ### END OF THE LAP.
        # PATH TRACKING:
        if (HalfTrack == 1 and (LocalState[4] <= map.TrackLength / 4)):
            HalfTrack = 0
            LapNumber += 1
            SS = 0
            PlannerCounter = 0
            TimeCounter = 0

            TotalLapTime = datetime.datetime.now() - start_LapTimer
            print 'Lap completed in', TotalLapTime, 'seconds. Starting lap:', LapNumber, '\n'
            TLAPTIME[LapNumber - 1] = TotalLapTime.total_seconds()
            start_LapTimer = datetime.datetime.now()

        # RACING:
        elif ((LapNumber >= 1) and (np.abs(GlobalState[3]) < 0.1)
              and (LocalState[4] >= (map.TrackLength - map.TrackLength / 10))):
            LapNumber += 1
            SS = 0
            # PlannerCounter  = TrackCounter

            TotalLapTime = datetime.datetime.now() - start_LapTimer
            print 'Lap completed in', TotalLapTime, 'seconds. Starting lap:', LapNumber, '. PlannerCounter = ', PlannerCounter, '\n'
            TLAPTIME[LapNumber - 1] = TotalLapTime.total_seconds()
            start_LapTimer = datetime.datetime.now()

            if LapNumber > NumberOfLaps:
                print('RunController = 0')
                RunController = 0

        startTimer = datetime.datetime.now()

        oldU = uApplied
        uApplied = np.array([cmd.servo, cmd.motor])

        if LapNumber == 0:
            Controller.OldSteering.append(
                cmd.servo)  # meto al final del vector
            Controller.OldAccelera.append(cmd.motor)
            Controller.OldSteering.pop(0)
            Controller.OldAccelera.pop(0)
        else:
            Controller_TT.OldSteering.append(
                cmd.servo)  # meto al final del vector
            Controller_TT.OldAccelera.append(cmd.motor)
            Controller_TT.OldSteering.pop(0)
            Controller_TT.OldAccelera.pop(0)

        ### Publish input ###
        input_commands.publish(cmd)

        ###################################################################################################
        ###################################################################################################

        if first_it < 10:
            # print('Iteration = ', first_it)
            vel_ref = np.ones(N)
            xx, uu = predicted_vectors_generation(N, LocalState, uApplied, dt)
            Controller.solve(LocalState[0:6], xx, uu, NN_LPV_MPC, vel_ref, 0,
                             0, 0, first_it)
            first_it = first_it + 1
            # print('---> Controller.uPred = ', Controller.uPred)

            Controller.OldPredicted = np.hstack(
                (Controller.OldSteering[0:len(Controller.OldSteering) - 1],
                 Controller.uPred[Controller.steeringDelay:Controller.N, 0]))
            Controller.OldPredicted = np.concatenate(
                (np.matrix(Controller.OldPredicted).T,
                 np.matrix(Controller.uPred[:, 1]).T),
                axis=1)

        else:

            NN_LPV_MPC = False
            if LapNumber == 0:  # PATH TRACKING : First lap at 1 m/s
                vel_ref = np.ones(N + 1)
                curv_ref = np.zeros(N)

                LPV_States_Prediction, A_L, B_L, C_L = Controller.LPVPrediction(
                    LocalState[0:6], Controller.uPred, vel_ref, curv_ref,
                    Cf_new, LapNumber)

                Controller.solve(LPV_States_Prediction[0, :],
                                 LPV_States_Prediction, Controller.uPred,
                                 NN_LPV_MPC, vel_ref, A_L, B_L, C_L, first_it)

                # IDENT_DATA[Counter,:] = [LocalState[0], LocalState[1], LocalState[2], uApplied[0], uApplied[1]]

                Controller_TT.uPred = Controller.uPred

            else:  # TRAJECTORY TRACKING

                # Offline planning data:
                # vel_ref     = VEL_Planner[0, PlannerCounter:PlannerCounter+N+1]
                # curv_ref    = CURV_Planner[0, PlannerCounter:PlannerCounter+N]

                # VEL_REF_vector     = planning_data.vx_d[0:N+10]
                # CURV_REF_vector    = planning_data.curv_d[0:N+10]

                # if index < 10:
                #     vel_ref     = VEL_REF_vector[index:index+N]
                #     curv_ref    = CURV_REF_vector[index:index+N]
                #     index += 1
                # else:
                #     index = 0

                # Online planning data:curv_ref
                # vel_ref     = planning_data.vx_d[0:N]
                # curv_ref    = planning_data.curv_d[0:N]

                LPV_States_Prediction, A_L, B_L, C_L = Controller_TT.LPVPrediction(
                    LocalState[0:6], Controller_TT.uPred, vel_ref, curv_ref,
                    Cf_new, LapNumber)

                Controller_TT.solve(LocalState[0:6], 0.0, Controller_TT.uPred,
                                    NN_LPV_MPC, vel_ref, A_L, B_L, C_L,
                                    first_it)

        ###################################################################################################
        ###################################################################################################

        if first_it > 19:
            new_LPV_States_Prediction = LPV_States_Prediction[0, :]
            for i in range(1, N):
                new_LPV_States_Prediction = np.hstack(
                    (new_LPV_States_Prediction, LPV_States_Prediction[i, :]))
            PREDICTED_DATA[Counter, :] = new_LPV_States_Prediction

        if LapNumber == 0:
            cmd.servo = Controller.uPred[0 + Controller.steeringDelay, 0]
            cmd.motor = Controller.uPred[0 + Controller.velocityDelay, 1]
        else:
            cmd.servo = Controller_TT.uPred[0 + Controller.steeringDelay, 0]
            cmd.motor = Controller_TT.uPred[0 + Controller.velocityDelay, 1]

        #print Controller.uPred[0, :]

        endTimer = datetime.datetime.now()
        deltaTimer = endTimer - startTimer

        # ESTO HABRA QUE RESCATARLO PARA PRUEBAS FISICAS...
        # else:   # If car out of the track
        #     cmd.servo = 0
        #     cmd.motor = 0
        #     input_commands.publish(cmd)

        ## Record Prediction
        if LapNumber < 1:
            OL_predictions.s = Controller.xPred[:, 4]
            OL_predictions.ex = []
            OL_predictions.ey = Controller.xPred[:, 5]
            OL_predictions.epsi = Controller.xPred[:, 3]
        else:
            OL_predictions.s = Controller_TT.xPred[:, 4]
            OL_predictions.ex = []
            OL_predictions.ey = Controller_TT.xPred[:, 5]
            OL_predictions.epsi = Controller_TT.xPred[:, 3]
            ALL_LOCAL_DATA[CounterRacing, :] = np.hstack(
                (LocalState, uApplied))
            GLOBAL_DATA[CounterRacing, :] = [
                GlobalState[3], GlobalState[4], GlobalState[5]
            ]
            CounterRacing += 1

        pred_treajecto.publish(OL_predictions)

        # ClosedLoopData.addMeasurement(GlobalState, LocalState, uApplied, Counter, deltaTimer.total_seconds())
        # Data_for_RMSE[TimeCounter,:] = [ LocalState[0], LocalState[5], LocalState[3], LocalState[7]]
        ELAPSD_TIME[Counter, :] = deltaTimer.total_seconds()

        # Publishing important info about the racing:
        rac_info.LapNumber = LapNumber
        # rac_info.PlannerCounter = PlannerCounter
        racing_info.publish(rac_info)

        # Increase time counter and ROS sleep()

        # print PlannerCounter

        TimeCounter += 1
        PlannerCounter += 1
        # if PlannerCounter > 580: #offline racing planning
        if PlannerCounter > 999:
            cmd.servo = 0
            cmd.motor = 0
            input_commands.publish(cmd)
            day = '31_7_19'
            num_test = 'Test_1'
            newpath = '/home/euge/GitHub/barc/results_simu_test/' + day + '/' + num_test + '/'
            if not os.path.exists(newpath):
                os.makedirs(newpath)
            np.savetxt(newpath + '/ALL_LOCAL_DATA.dat',
                       ALL_LOCAL_DATA,
                       fmt='%.5e')
            np.savetxt(newpath + '/PREDICTED_DATA.dat',
                       PREDICTED_DATA,
                       fmt='%.5e')
            np.savetxt(newpath + '/GLOBAL_DATA.dat', GLOBAL_DATA, fmt='%.5e')
            np.savetxt(newpath + '/References.dat', References, fmt='%.5e')
            np.savetxt(newpath + '/TLAPTIME.dat', TLAPTIME, fmt='%.5e')
            np.savetxt(newpath + '/ELAPSD_TIME.dat', ELAPSD_TIME, fmt='%.5e')
            quit()

        Counter += 1
        rate.sleep()

    # END WHILE

    # Save Data
    # file_data = open(sys.path[0]+'/data/'+mode+'/ClosedLoopData'+"LPV_MPC"+'.obj', 'wb')
    # pickle.dump(ClosedLoopData, file_data)
    # pickle.dump(Controller, file_data)

#############################################################

# file_data = open(newpath+'/ClosedLoopDataLPV_MPC.obj', 'wb')
# pickle.dump(ClosedLoopData, file_data)
# pickle.dump(Controller, file_data)
# file_data.close()

# INFO_data = open(newpath+'/INFO.txt', 'wb')
# INFO_data.write('Running in Track number ')
# INFO_data.write('%d \n' % Planning_Track)
# #INFO_data.write(' ')
# INFO_data.close()

#############################################################

# plotTrajectory(map, ClosedLoopData, Complete_Vel_Vect)

    quit()
Exemplo n.º 10
0
 def publish_throttle_steering(self, action):
     msg = ECU()
     msg.motor = self.throttle
     msg.servo = action * (500 / 0.366519) + 1520
     self.ecu.publish(msg)
    def spin(self):
        rospy.sleep(self.init_time)
        self.start_time = rospy.get_rostime().to_sec()

        while not rospy.is_shutdown():
            t = rospy.get_rostime().to_sec()
            ecu_msg = ECU()

            if t - self.start_time >= self.max_time:
                ecu_msg.servo = 0.0
                ecu_msg.motor = 0.0
                # Publish the final motor and steering commands
                self.ecu_pub.publish(ecu_msg)

                self.bond_log.break_bond()
                self.bond_ard.break_bond()
                rospy.signal_shutdown(
                    'Max time of %g reached, controller shutting down...' %
                    self.max_time)

            EV_state = self.state
            TV_pred = self.tv_state_prediction[:self.N + 1]

            EV_x, EV_y, EV_heading, EV_v = EV_state
            TV_x, TV_y, TV_heading, TV_v = TV_pred[0]

            X_ref = EV_x + np.arange(self.N + 1) * self.dt * self.v_ref
            Z_ref = np.zeros((self.N + 1, self.n_x))
            Z_ref[:, 0] = X_ref

            self.obs[0] = get_car_poly(TV_pred, self.TV_W, self.TV_L)

            if self.ev_state_prediction is None:
                Z_ws = Z_ref
                U_ws = np.zeros((self.N, self.n_u))
            else:
                Z_ws = np.vstack(
                    (self.ev_state_prediction[1:],
                     self.dynamics.f_dt(self.ev_state_prediction[-1],
                                        self.ev_input_prediction[-1],
                                        type='numpy')))
                U_ws = np.vstack((self.ev_input_prediction[1:],
                                  self.ev_input_prediction[-1]))

            obca_mpc_ebrake = False
            obca_mpc_safety = False
            status_ws = self.obca_controller.solve_ws(Z_ws, U_ws, self.obs)
            if status_ws['success']:
                rospy.loginfo('Warm start solved in %g s' %
                              status_ws['solve_time'])
                Z_obca, U_obca, status_sol = self.obca_controller.solve(
                    EV_state, self.last_input, Z_ref, self.obs)

            if not status_ws['success'] or not status_sol['success']:
                obca_mpc_safety = True
                rospy.loginfo(
                    'OBCA MPC not feasible, activating safety controller')

            if obca_mpc_safety:
                self.safety_controller.set_accel_ref(EV_v * np.cos(EV_heading),
                                                     TV_v * np.cos(TV_heading))
                u_safe = self.safety_controller.solve(EV_state, TV_pred,
                                                      self.last_input)

                z_next = self.dynamics.f_dt(EV_state, u_safe, type='numpy')
                collision = check_collision_poly(z_next,
                                                 (self.EV_W, self.EV_L),
                                                 TV_pred[1],
                                                 (self.TV_W, self.TV_L))
                if collision:
                    obca_mpc_ebrake = True
                    u_safe = self.emergency_controller.solve(
                        EV_state, TV_pred, self.last_input)

                U_pred = np.vstack((u_safe, np.zeros((self.N - 1, self.n_u))))
                Z_pred = np.vstack((EV_state, np.zeros((self.N, self.n_x))))
                for i in range(self.N):
                    Z_pred[i + 1] = self.dynamics.f_dt(Z_pred[i],
                                                       U_pred[i],
                                                       type='numpy')
            else:
                Z_pred, U_pred = Z_obca, U_obca

            if obca_mpc_ebrake:
                fsm_state = 'Emergency-Break'
            elif obca_mpc_safety:
                fsm_state = 'Safe-Infeasible'
            else:
                fsm_state = 'HOBCA-Unlocked'

            self.ev_state_prediction = Z_pred
            self.ev_input_prediction = U_pred

            self.last_input = U_pred[0]

            ecu_msg = ECU()
            ecu_msg.servo = U_pred[0, 0]
            ecu_msg.motor = U_pred[0, 1]
            self.ecu_pub.publish(ecu_msg)

            pred_msg = Prediction()
            pred_msg.x = Z_pred[:, 0]
            pred_msg.y = Z_pred[:, 1]
            pred_msg.psi = Z_pred[:, 2]
            pred_msg.v = Z_pred[:, 3]
            pred_msg.df = U_pred[:, 0]
            pred_msg.a = U_pred[:, 1]
            self.pred_pub.publish(pred_msg)

            fsm_state_msg = FSMState()
            fsm_state_msg.fsm_state = fsm_state
            self.fsm_state_pub.publish(fsm_state_msg)

            self.rate.sleep()
Exemplo n.º 12
0
def main():
    # Initializa ROS node
    rospy.init_node("LMPC")
    input_commands = rospy.Publisher('ecu', ECU, queue_size=1)
    pred_treajecto = rospy.Publisher('OL_predictions',
                                     prediction,
                                     queue_size=1)
    sel_safe_set = rospy.Publisher('SS', SafeSetGlob, queue_size=1)

    mode = rospy.get_param("/control/mode")

    loop_rate = 30.0
    dt = 1.0 / loop_rate
    rate = rospy.Rate(loop_rate)

    Steering_Delay = 1

    ### BUILDING THE GRID FOR TUNNING:
    Data_for_RMSE = np.zeros((2000, 3))
    VQ_ve = np.array([100.0, 150.0, 200.0, 250.0])
    VQ_ye = np.array([50.0, 100.0, 150.0, 200.0])
    VQ_thetae = np.array([
        150.0, 200.0, 250.0, 300.0, 350.0, 400.0, 450.0, 500.0, 550.0, 600.0,
        650.0, 700.0, 750.0, 800.0
    ])
    grid_length = len(VQ_ve) * len(VQ_ye) * len(VQ_thetae)
    Q_matrix_grid = np.zeros((grid_length, 3))

    counter = 0
    for i in range(0, len(VQ_ve)):
        Q_ve = VQ_ve[i]
        for j in range(0, len(VQ_ye)):
            Q_ye = VQ_ye[j]
            for k in range(0, len(VQ_thetae)):
                Q_thetae = VQ_thetae[k]
                Q_matrix_grid[counter, :] = [Q_ve, Q_ye, Q_thetae]
                counter += 1
    #print Q_matrix_grid

    # Objects initializations
    SS_glob_sel = SafeSetGlob()
    OL_predictions = prediction()
    cmd = ECU()  # Command message
    cmd.servo = 0.0
    cmd.motor = 0.0
    ClosedLoopData = ClosedLoopDataObj(dt, 6000, 0)  # Closed-Loop Data
    estimatorData = EstimatorData()
    map = Map()  # Map

    PickController = "LPV_MPC"

    first_it = 1
    NumberOfLaps = grid_length
    vt = 1.0
    PathFollowingLaps = 0  #EA: With this at 0 skips the first PID lap

    # Initialize variables for main loop
    GlobalState = np.zeros(6)
    LocalState = np.zeros(6)
    HalfTrack = 0
    LapNumber = 0
    RunController = 1
    PlotingCounter = 0
    uApplied = np.array([0.0, 0.0])
    oldU = np.array([0.0, 0.0])

    RMSE_ve = np.zeros(grid_length)
    RMSE_ye = np.zeros(grid_length)
    RMSE_thetae = np.zeros(grid_length)
    RMSE_matrix = np.zeros(grid_length)

    # Loop running at loop rate
    TimeCounter = 0
    KeyInput = raw_input("Press enter to start the controller... \n")
    oneStepPrediction = np.zeros(6)

    ### CONTROLLER INITIALIZATION:
    ### 33 ms - 10 Hp
    Q = np.diag([100.0, 1.0, 1.0, 50.0, 0.0, 1000.0])
    R = 1 * np.diag([1.0, 0.5])  # delta, a
    dR = 30 * np.array([2.0, 1.5])  # Input rate cost u
    N = 14
    Controller = PathFollowingLPV_MPC(Q, R, dR, N, vt, dt, map, "OSQP",
                                      Steering_Delay)
    print "Q matrix: \n", Q, "\n"

    while (not rospy.is_shutdown()) and RunController == 1:
        # Read Measurements
        GlobalState[:] = estimatorData.CurrentState
        LocalState[:] = estimatorData.CurrentState  #The current estimated state vector

        # EA: s, ey, epsi
        LocalState[4], LocalState[5], LocalState[
            3], insideTrack = map.getLocalPosition(GlobalState[4],
                                                   GlobalState[5],
                                                   GlobalState[3])
        if LocalState[0] < 0.01:
            LocalState[0] = 0.01

        # Check if the lap has finished
        if LocalState[4] >= 3 * map.TrackLength / 4:
            HalfTrack = 1

        ### END OF THE LAP:
        if HalfTrack == 1 and (LocalState[4] <= map.TrackLength / 4):
            HalfTrack = 0
            LapNumber += 1

            print "Lap completed starting lap:", LapNumber, ". Lap time: ", float(
                TimeCounter) / loop_rate

            if LapNumber > 1:
                print "Recording RMSE... \n"
                PointAndTangent = map.PointAndTangent
                cur, vel = Curvature(LocalState[4], PointAndTangent)
                RMSE_ve[LapNumber - 2] = np.sqrt(
                    ((vel - Data_for_RMSE[0:TimeCounter, 0])**2).mean())
                RMSE_ye[LapNumber - 2] = np.sqrt((Data_for_RMSE[0:TimeCounter,
                                                                1]**2).mean())
                RMSE_thetae[LapNumber - 2] = np.sqrt(
                    (Data_for_RMSE[0:TimeCounter, 2]**2).mean())
                Data_for_RMSE = np.zeros((2000, 3))

            TimeCounter = 0
            first_it = 1
            Q = np.diag([
                Q_matrix_grid[LapNumber - 1,
                              0], 1.0, 1.0, Q_matrix_grid[LapNumber - 1, 1],
                0.0, Q_matrix_grid[LapNumber - 1, 2]
            ])
            R = 1 * np.diag([1.0, 0.5])  # delta, a
            dR = 30 * np.array([2.0, 1.5])  # Input rate cost u
            N = 14
            Controller = PathFollowingLPV_MPC(Q, R, dR, N, vt, dt, map, "OSQP",
                                              Steering_Delay)
            print "Q matrix: \n", Q, "\n"

            if LapNumber >= NumberOfLaps:
                RunController = 0

        # If inside the track publish input
        if (insideTrack == 1):
            startTimer = datetime.datetime.now()

            oldU = uApplied
            uApplied = np.array([cmd.servo, cmd.motor])
            #Controller.OldInput = uApplied

            #print "Insert steering in the last space of the vector...", "\n"
            Controller.OldSteering.append(
                cmd.servo)  # meto al final del vector
            Controller.OldAccelera.append(cmd.motor)
            #print "1o-Controller.OldSteering: ",Controller.OldSteering, "\n"
            #print "Remove the first element of the vector...", "\n"
            Controller.OldSteering.pop(0)
            Controller.OldAccelera.pop(0)
            #print "2o-Controller.OldSteering: ",Controller.OldSteering, "\n"

            ### Publish input ###
            input_commands.publish(cmd)
            #print "Publishing: ", cmd.servo, "\n"

            oneStepPredictionError = LocalState - oneStepPrediction  # Subtract the local measurement to the previously predicted one step

            uAppliedDelay = [
                Controller.OldSteering[-1 - Controller.steeringDelay],
                Controller.OldAccelera[-1]
            ]
            #print "uAppliedDelay: ",Controller.OldSteering[-1 - Controller.steeringDelay], "\n"

            oneStepPrediction, oneStepPredictionTime = Controller.oneStepPrediction(
                LocalState, uAppliedDelay, 1)

            if first_it < 10:  # EA: Starting mode:

                xx = np.array([[
                    LocalState[0] + 0.05, LocalState[1], 0., 0.000001,
                    LocalState[4], 0.0001
                ],
                               [
                                   LocalState[0] + 0.2, LocalState[1], 0.,
                                   0.000001, LocalState[4] + 0.01, 0.0001
                               ],
                               [
                                   LocalState[0] + 0.4, LocalState[1], 0.,
                                   0.000001, LocalState[4] + 0.02, 0.0001
                               ],
                               [
                                   LocalState[0] + 0.6, LocalState[1], 0.,
                                   0.000001, LocalState[4] + 0.04, 0.0001
                               ],
                               [
                                   LocalState[0] + 0.7, LocalState[1], 0.,
                                   0.000001, LocalState[4] + 0.07, 0.0001
                               ],
                               [
                                   LocalState[0] + 0.8, LocalState[1], 0.,
                                   0.000001, LocalState[4] + 0.1, 0.0001
                               ],
                               [
                                   LocalState[0] + 0.8, LocalState[1], 0.,
                                   0.000001, LocalState[4] + 0.14, 0.0001
                               ],
                               [
                                   LocalState[0] + 1.0, LocalState[1], 0.,
                                   0.000001, LocalState[4] + 0.18, 0.0001
                               ],
                               [
                                   LocalState[0] + 1.05, LocalState[1], 0.,
                                   0.000001, LocalState[4] + 0.23, 0.0001
                               ],
                               [
                                   LocalState[0] + 1.05, LocalState[1], 0.,
                                   0.000001, LocalState[4] + 0.55, 0.0001
                               ],
                               [
                                   LocalState[0] + 1.05, LocalState[1], 0.,
                                   0.000001, LocalState[4] + 0.66, 0.0001
                               ],
                               [
                                   LocalState[0] + 1.05, LocalState[1], 0.,
                                   0.000001, LocalState[4] + 0.77, 0.0001
                               ],
                               [
                                   LocalState[0] + 1.05, LocalState[1], 0.,
                                   0.000001, LocalState[4] + 0.89, 0.0001
                               ],
                               [
                                   LocalState[0] + 1.0, LocalState[1], 0.,
                                   0.000001, LocalState[4] + 0.999, 0.0001
                               ]])
                uu = np.array([[0., 0.], [0., 0.3], [0., 0.5], [0., 0.7],
                               [0., 0.9], [0., 1.0], [0., 1.0], [0., 1.0],
                               [0., 1.0], [0., 0.8], [0., 0.8], [0., 0.8],
                               [0., 0.8], [0., 0.8]])

                Controller.solve(LocalState, xx, uu)
                first_it = first_it + 1

                #print "Resolving MPC...", "\n "
                #print "Steering predicted: ",Controller.uPred[:,0] , "\n "
                #Controller.OldPredicted = np.hstack((Controller.OldSteering, Controller.uPred[Controller.steeringDelay:Controller.N-1,0]))
                #Controller.OldPredicted = np.concatenate((np.matrix(Controller.OldPredicted).T, np.matrix(Controller.uPred[:,1]).T), axis=1)

                Controller.OldPredicted = np.hstack(
                    (Controller.OldSteering[0:len(Controller.OldSteering) - 1],
                     Controller.uPred[Controller.steeringDelay:Controller.N,
                                      0]))
                Controller.OldPredicted = np.concatenate(
                    (np.matrix(Controller.OldPredicted).T,
                     np.matrix(Controller.uPred[:, 1]).T),
                    axis=1)

                #print "OldPredicted: ",Controller.OldPredicted[:,0], "\n"

                # We store the predictions since we are going to rebuild the controller object:
                U_pred = Controller.uPred
                last_Hp = len(uu)
            else:

                # # Recomputamos el objeto controller con nuevo Hp:
                # PointAndTangent = map.PointAndTangent
                # cur, vel = Curvature(LocalState[4], PointAndTangent)
                # print "Curvature: ",cur, "\n"
                # if cur > 0.1:
                #     Q  = np.diag([100.0, 1.0, 1.0, 20.0, 0.0, 700.0])
                #     R  = 0 * np.diag([1.0, 1.0])  # delta, a
                #     dR = 40 * np.array([2.0, 1.5])  # Input rate cost u
                #     N  = 10
                #     Controller = PathFollowingLPV_MPC(Q, R, dR, N, vt, dt, map, "OSQP", Steering_Delay)
                #     print "Hp = ", N, "\n"
                #     if last_Hp == 4:
                #         last_input = U_pred[3,:]
                #         for i in range(last_Hp, N):
                #             U_pred = np.vstack((U_pred, last_input))
                #         LPV_States_Prediction = Controller.LPVPrediction(LocalState, U_pred)
                #         Controller.solve(LPV_States_Prediction[0,:], LPV_States_Prediction, U_pred)
                #         U_pred = Controller.uPred
                #         #print U_pred
                #         last_Hp = N
                #     else:
                #         LPV_States_Prediction = Controller.LPVPrediction(LocalState, U_pred)
                #         Controller.solve(LPV_States_Prediction[0,:], LPV_States_Prediction, U_pred)
                #         U_pred = Controller.uPred
                #         #print U_pred
                #         last_Hp = N
                # else:
                #     Q  = np.diag([100.0, 1.0, 1.0, 20.0, 0.0, 700.0])
                #     R  = 0 * np.diag([1.0, 1.0])  # delta, a
                #     dR = 40 * np.array([2.0, 1.5])  # Input rate cost u
                #     N  = 4
                #     Controller = PathFollowingLPV_MPC(Q, R, dR, N, vt, dt, map, "OSQP", Steering_Delay)
                #     print "Hp = ", N, "\n"
                #     LPV_States_Prediction = Controller.LPVPrediction(LocalState, U_pred)
                #     Controller.solve(LPV_States_Prediction[0,:], LPV_States_Prediction, U_pred)
                #     U_pred = Controller.uPred
                #     #print "U predicted:",U_pred, "\n"
                #     last_Hp = N

                # Old version:
                #LPV_States_Prediction = Controller.LPVPrediction(LocalState, Controller.uPred)
                #Controller.solve(LPV_States_Prediction[0,:], LPV_States_Prediction, Controller.uPred)
                #print "Resolving MPC...", "\n "
                LPV_States_Prediction = Controller.LPVPrediction(
                    LocalState, Controller.OldPredicted)
                Controller.solve(LPV_States_Prediction[0, :],
                                 LPV_States_Prediction,
                                 Controller.OldPredicted)
            ###################################################################################################
            ###################################################################################################

            cmd.servo = Controller.uPred[0 + Controller.steeringDelay, 0]
            cmd.motor = Controller.uPred[0, 1]
            #print "Steering que SE PUBLICARA teniendo en cuenta el delay: ","\n", "------>", cmd.servo, "\n \n \n \n \n"

            ##################################################################
            # GETTING DATA FOR IDENTIFICATION:
            # cmd.servo = 0.5*np.cos(50*TimeCounter)
            # if LocalState[0]>1.6:
            #     cmd.motor = 0.0
            # else:
            #     cmd.motor = 1.0
            ##################################################################

            #print Controller.uPred[steps_Delay,0], Controller.uPred[0,0]

            # if (Controller.solverTime.total_seconds() + Controller.linearizationTime.total_seconds() + oneStepPredictionTime.total_seconds() > dt):
            #     print "NOT REAL-TIME FEASIBLE!!"
            #     print "Solver time: ", Controller.solverTime.total_seconds(), " Linearization Time: ", Controller.linearizationTime.total_seconds() + oneStepPredictionTime.total_seconds()

            endTimer = datetime.datetime.now()
            deltaTimer = endTimer - startTimer
            #print "Tot Solver Time: ", deltaTimer.total_seconds()

        else:  # If car out of the track
            cmd.servo = 0
            cmd.motor = 0
            input_commands.publish(cmd)

            print " Current Input: ", cmd.servo, cmd.motor
            print " X, Y State: ", GlobalState
            print " Current State: ", LocalState

        # Record Prediction
        OL_predictions.s = Controller.xPred[:, 4]
        OL_predictions.ey = Controller.xPred[:, 5]
        OL_predictions.epsi = Controller.xPred[:, 3]
        pred_treajecto.publish(OL_predictions)
        ClosedLoopData.addMeasurement(GlobalState, LocalState,
                                      uApplied, PlotingCounter,
                                      deltaTimer.total_seconds())
        Data_for_RMSE[TimeCounter, :] = [
            LocalState[0], LocalState[5], LocalState[3]
        ]

        # Increase time counter and ROS sleep()
        TimeCounter = TimeCounter + 1
        PlotingCounter += 1
        rate.sleep()

    # Save Data
    file_data = open(
        sys.path[0] + '/data/' + mode + '/ClosedLoopData' + "LPV_MPC" + '.obj',
        'wb')
    pickle.dump(ClosedLoopData, file_data)
    pickle.dump(Controller, file_data)
    #pickle.dump(OpenLoopData, file_data)

    print " \n \n \n Root Mean Squared Vel Error Normalised: \n", np.divide(
        RMSE_ve[0:LapNumber - 1], np.amax(RMSE_ve[0:LapNumber - 1])), "\n"
    print "Root Mean Squared Lateral Error Normalised: \n", np.divide(
        RMSE_ye[0:LapNumber - 1], np.amax(RMSE_ye[0:LapNumber - 1])), "\n"
    print "Root Mean Squared Theta Error Normalised: \n", np.divide(
        RMSE_thetae[0:LapNumber - 1],
        np.amax(RMSE_thetae[0:LapNumber - 1])), "\n"

    print len(RMSE_thetae[0:LapNumber - 1])
    for k in range(0, len(RMSE_thetae[0:LapNumber - 1]) - 1):
        RMSE_matrix[k] = RMSE_ve[k] + RMSE_ye[k] + RMSE_thetae[k]

    print "Best tunning: ", Q_matrix_grid[np.argmin(RMSE_matrix)], "\n \n \n"

    #plotTrajectory(map, ClosedLoopData)

    file_data.close()
Exemplo n.º 13
0
    def spin(self):
        start_time_msg = rospy.wait_for_message('/start_time',
                                                Float64,
                                                timeout=10.0)
        self.start_time = start_time_msg.data
        rospy.loginfo('============ DIRECT: Node START, time %g ============' %
                      self.start_time)

        while not rospy.is_shutdown():
            t = rospy.get_rostime().to_sec() - self.start_time

            # Get EV state and TV prediction at current time
            EV_state = self.state
            TV_pred = self.tv_state_prediction[:self.N + 1]

            EV_x, EV_y, EV_heading, EV_v = EV_state
            TV_x, TV_y, TV_heading, TV_v = TV_pred[0]

            ecu_msg = ECU()
            ecu_msg.servo = 0.0
            ecu_msg.motor = 0.0

            if t >= self.init_time and not self.task_start:
                self.task_start = True
                rospy.loginfo(
                    '============ DIRECT: Controler START ============')

            if t >= self.max_time and not self.task_finished:
                shutdown_msg = '============ DIRECT: Max time of %g reached. Controler SHUTTING DOWN ============' % self.max_time
                self.task_finished = True
            elif (EV_x < self.x_boundary[0] or EV_x > self.x_boundary[1]) or (
                    EV_y < self.y_boundary[0]
                    or EV_y > self.y_boundary[1]) and not self.task_finished:
                # Check if car has left the experiment area
                self.task_finished = True
                shutdown_msg = '============ DIRECT: Track bounds exceeded reached. Controler SHUTTING DOWN ============'
            elif np.abs(EV_x - self.x_goal) <= 0.10 and not self.task_finished:
                self.task_finished = True
                shutdown_msg = '============ DIRECT: Goal position reached. Controler SHUTTING DOWN ============'

            if self.task_finished:
                self.ecu_pub.publish(ecu_msg)
                self.bond_log.break_bond()
                self.bond_ard.break_bond()
                rospy.loginfo(shutdown_msg)
                rospy.signal_shutdown(shutdown_msg)

            self.obs[0] = get_car_poly(TV_pred, self.TV_W, self.TV_L)

            X_ref = EV_x + np.arange(self.N + 1) * self.dt * self.v_ref
            Z_ref = np.zeros((self.N + 1, self.n_x))
            Z_ref[:, 0] = X_ref

            if self.ev_state_prediction is None:
                Z_ws = Z_ref
                U_ws = np.zeros((self.N, self.n_u))
            else:
                Z_ws = np.vstack(
                    (self.ev_state_prediction[1:],
                     self.dynamics.f_dt(self.ev_state_prediction[-1],
                                        self.ev_input_prediction[-1],
                                        type='numpy')))
                U_ws = np.vstack((self.ev_input_prediction[1:],
                                  self.ev_input_prediction[-1]))

            obca_mpc_ebrake = False
            obca_mpc_safety = False
            status_ws = self.obca_controller.solve_ws(Z_ws, U_ws, self.obs)
            if status_ws['success']:
                # rospy.loginfo('Warm start solved in %g s' % status_ws['solve_time'])
                Z_obca, U_obca, status_sol = self.obca_controller.solve(
                    EV_state, self.last_input, Z_ref, self.obs)

            if not status_ws['success'] or not status_sol['success']:
                obca_mpc_safety = True
                rospy.loginfo(
                    '============ DIRECT: OBCA MPC not feasible, activating safety controller ============'
                )

            if obca_mpc_safety:
                self.safety_controller.set_accel_ref(EV_v * np.cos(EV_heading),
                                                     TV_v * np.cos(TV_heading))
                u_safe = self.safety_controller.solve(EV_state, TV_pred,
                                                      self.last_input)

                z_next = self.dynamics.f_dt(EV_state, u_safe, type='numpy')
                collision = check_collision_poly(z_next,
                                                 (self.EV_W, self.EV_L),
                                                 TV_pred[1],
                                                 (self.TV_W, self.TV_L))
                if collision:
                    obca_mpc_ebrake = True
                    u_safe = self.emergency_controller.solve(
                        EV_state, TV_pred, self.last_input)
                    rospy.loginfo(
                        '============ DIRECT: Applying ebrake control ============'
                    )
                else:
                    rospy.loginfo(
                        '============ DIRECT: Applying safety control ============'
                    )

                U_pred = np.vstack((u_safe, np.zeros((self.N - 1, self.n_u))))
                Z_pred = np.vstack((EV_state, np.zeros((self.N, self.n_x))))
                for i in range(self.N):
                    Z_pred[i + 1] = self.dynamics.f_dt(Z_pred[i],
                                                       U_pred[i],
                                                       type='numpy')
            else:
                Z_pred, U_pred = Z_obca, U_obca
                rospy.loginfo(
                    '============ DIRECT: Applying HOBCA control ============')

            if obca_mpc_ebrake:
                fsm_state = 'Emergency-Break'
            elif obca_mpc_safety:
                fsm_state = 'Safe-Infeasible'
            else:
                fsm_state = 'HOBCA-Unlocked'

            if not self.task_start:
                rospy.loginfo(
                    '============ DIRECT: Node up time: %g s. Controller not yet started ============'
                    % t)
                self.last_input = np.zeros(self.n_u)
            else:
                ecu_msg.servo = U_pred[0, 0]
                ecu_msg.motor = U_pred[0, 1]
                self.last_input = U_pred[0]

            # deadband = 0.01
            # if np.abs(ecu_msg.motor) <= deadband:
            #     ecu_msg.motor = 0.0
            # elif ecu_msg.motor > deadband:
            #     ecu_msg.motor = ecu_msg.motor - deadband
            # else:
            #     ecu_msg.motor = ecu_msg.motor + deadband

            self.ecu_pub.publish(ecu_msg)

            self.ev_state_prediction = Z_pred
            self.ev_input_prediction = U_pred

            pred_msg = Prediction()
            pred_msg.x = Z_pred[:, 0]
            pred_msg.y = Z_pred[:, 1]
            pred_msg.psi = Z_pred[:, 2]
            pred_msg.v = Z_pred[:, 3]
            pred_msg.df = U_pred[:, 0]
            pred_msg.a = U_pred[:, 1]
            self.pred_pub.publish(pred_msg)

            fsm_state_msg = FSMState()
            fsm_state_msg.fsm_state = fsm_state
            self.fsm_state_pub.publish(fsm_state_msg)

            self.rate.sleep()
Exemplo n.º 14
0
            if key in moveBindings.keys():
                motor = moveBindings[key][0]
                servo = moveBindings[key][1]
            elif key in speedBindings.keys():
                speed = speed * speedBindings[key][0]
                turn = turn * speedBindings[key][1]
                if (status == 14):
                    print(msg)
                status = (status + 1) % 15
            else:
                motor = 0
                servo = 0
                if (key == '\x03'):
                    break

            ecu = ECU()
            ecu.motor = motor * speed
            ecu.servo = servo * turn
            pub.publish(ecu)

    except Exception as e:
        print(e)

    finally:
        ecu = ECU()
        ecu.motor = 0
        ecu.servo = 0
        pub.publish(ecu)

        termios.tcsetattr(sys.stdin, termios.TCSADRAIN, settings)
    def spin(self):
        start_time_msg = rospy.wait_for_message('/start_time',
                                                Float64,
                                                timeout=5.0)
        self.start_time = start_time_msg.data
        rospy.sleep(0.5)
        counter = 0
        rospy.loginfo('============ SAFETY: Node START, time %g ============' %
                      self.start_time)

        while not rospy.is_shutdown():
            t = rospy.get_rostime().to_sec() - self.start_time

            # Get EV state and TV prediction at current time
            EV_state = self.state
            TV_pred = self.tv_state_prediction[:self.N + 1]

            EV_x, EV_y, EV_heading, EV_v = EV_state
            TV_x, TV_y, TV_heading, TV_v = TV_pred[0]

            ecu_msg = ECU()
            ecu_msg.servo = 0.0
            ecu_msg.motor = 0.0

            if t >= self.init_time and not self.task_start:
                self.task_start = True
                rospy.loginfo(
                    '============ SAFETY: Controler START ============')

            if t >= self.max_time and not self.task_finish:
                self.task_finish = True
                shutdown_msg = '============ SAFETY: Max time of %g reached. Controler SHUTTING DOWN ============' % self.max_time
            elif (EV_x < self.x_boundary[0] or EV_x > self.x_boundary[1]
                  ) or (EV_y < self.y_boundary[0]
                        or EV_y > self.y_boundary[1]) and not self.task_finish:
                # Check if car has left the experiment area
                self.task_finish = True
                shutdown_msg = '============ SAFETY: Track bounds exceeded. Controler SHUTTING DOWN ============'
            # elif np.abs(y) > 0.7 and np.abs(heading - np.pi/2) <= 10*np.pi/180:
            elif np.abs(EV_y) > 0.7:
                self.task_finish = True
                shutdown_msg = '============ SAFETY: Goal position reached. Controler SHUTTING DOWN ============'

            if self.task_finish:
                self.ecu_pub.publish(ecu_msg)
                self.bond_log.break_bond()
                self.bond_ard.break_bond()
                rospy.loginfo(shutdown_msg)
                rospy.signal_shutdown(shutdown_msg)

            # Compute the distance threshold for applying braking assuming max

    # decceleration is applied

            rel_vx = TV_v * np.cos(TV_heading) - EV_v * np.cos(EV_heading)
            min_ts = np.ceil(
                -rel_vx / np.abs(self.a_lim[0]) / self.dt
            )  # Number of timesteps requred for relative velocity to be zero
            v_brake = np.abs(
                rel_vx) + np.arange(min_ts + 1) * self.dt * self.a_lim[
                    0]  # Velocity when applying max decceleration
            brake_thresh = np.sum(
                np.abs(v_brake) * self.dt
            ) + 5 * self.collision_buffer_r  # Distance threshold for safety controller to be applied
            d = la.norm(np.array(
                [EV_x - TV_x,
                 EV_y - TV_y]))  # Distance between ego and target vehicles

            if d <= brake_thresh:
                self.safety_controller.set_accel_ref(EV_v * np.cos(EV_heading),
                                                     TV_v * np.cos(TV_heading))
            else:
                self.safety_controller.set_accel_ref(EV_v * np.cos(EV_heading),
                                                     self.v_ref)

            u_safe = self.safety_controller.solve(EV_state, TV_pred,
                                                  self.last_input)

            if not self.task_start:
                rospy.loginfo(
                    '============ SAFETY: Node up time: %g s. Controller not yet started ============'
                    % t)
                self.last_input = np.zeros(self.n_u)
            else:
                rospy.loginfo(
                    '============ SAFETY: Applying safety PID control ============'
                )
                ecu_msg.servo = u_safe[0]
                ecu_msg.motor = u_safe[1]
                self.last_input = u_safe

            self.ecu_pub.publish(ecu_msg)

            if self.task_start:
                counter += 1

            self.rate.sleep()
Exemplo n.º 16
0
    def spin(self):
        self.start_time = rospy.get_rostime().to_sec()
        counter = 0
        waypt_counter = 0
        self.start_pub.publish(Float64(self.start_time))
        rospy.loginfo('============ TRACKING: Node START, time %g ============' % self.start_time)

        while not rospy.is_shutdown():
            # Get state at current time
            state = self.state
            x, y, heading, v = state
            t = rospy.get_rostime().to_sec() - self.start_time

            ecu_msg = ECU()
            ecu_msg.servo = 0.0
            ecu_msg.motor = 0.0

            if t >= self.init_time and not self.task_start:
                self.task_start = True
                rospy.loginfo('============ TRACKING: Controler START ============')

            if t >= self.max_time and not self.task_finish:
                self.task_finish = True
                shutdown_msg = '============ TRACKING: Max time of %g reached. Controler SHUTTING DOWN ============' % self.max_time
            elif (x < self.x_boundary[0] or x > self.x_boundary[1]) or (y < self.y_boundary[0] or y > self.y_boundary[1]) and not self.task_finish:
                # Check if car has left the experiment area
                self.task_finish = True
                shutdown_msg = '============ TRACKING: Track bounds exceeded. Controler SHUTTING DOWN ============'
            # elif np.abs(y) > 0.7 and np.abs(heading - np.pi/2) <= 10*np.pi/180:
            elif np.abs(y) > 0.7:
                self.task_finish = True
                shutdown_msg = '============ TRACKING: Goal position reached. Controler SHUTTING DOWN ============'

            if self.task_finish:
                self.ecu_pub.publish(ecu_msg)
                self.bond_log.break_bond()
                self.bond_ard.break_bond()
                rospy.loginfo(shutdown_msg)
                rospy.signal_shutdown(shutdown_msg)

            if la.norm(np.array([x,y])-self.waypoints[waypt_counter]) <= 0.2 and waypt_counter < self.waypoints.shape[0]-1 and not self.wait:
                rospy.loginfo('============ TRACKING: Waypoint (%g,%g) reached ============' \
                    % (self.waypoints[waypt_counter,0], self.waypoints[waypt_counter,1]))
                self.wait = True
                self.tracking_controller.Q = np.array([0,0,0,10])
            if self.wait and counter >= self.next_ref_start[waypt_counter]:
                rospy.loginfo('============ TRACKING: Setting next waypoint (%g,%g) ============' \
                    % (self.waypoints[waypt_counter,0], self.waypoints[waypt_counter,1]))
                self.wait = False
                self.tracking_controller.Q = self.Q
                waypt_counter += 1

            if self.wait:
                Z_ref = np.zeros((self.N+1, self.n_x))
            elif counter >= self.traj_len - 1:
                Z_ref = np.tile(self.trajectory[-1], (self.N+1,1))
                Z_ref[:,3] = 0
                rospy.loginfo('============ TRACKING: End of trajectory reached ============')
            elif counter >= self.traj_len - (self.N+1):
                Z_ref = np.vstack((self.trajectory[counter:], np.tile(self.trajectory[-1], ((self.N+1)-(self.traj_len-counter),1))))
                Z_ref[:,3] = 0
            else:
                Z_ref = self.trajectory[counter:counter+self.N+1]

            if self.state_prediction is None:
                Z_ws = Z_ref
                U_ws = np.zeros((self.N, self.n_u))
            else:
                Z_ws = np.vstack((self.state_prediction[1:],
                    self.dynamics.f_dt(self.state_prediction[-1], self.input_prediction[-1], type='numpy')))
                U_ws = np.vstack((self.input_prediction[1:],
                    self.input_prediction[-1]))

            Z_pred, U_pred, status_sol = self.tracking_controller.solve(state, self.last_input, Z_ref, Z_ws, U_ws)

            if not self.task_start:
                rospy.loginfo('============ TRACKING: Node up time: %g s. Controller not yet started ============' % t)
                self.last_input = np.zeros(self.n_u)
            elif self.wait:
                rospy.loginfo('============ TRACKING: Stopping, waiting for reference to move past transition ============')
                ecu_msg.servo = U_pred[0,0]
                ecu_msg.motor = U_pred[0,1]
                self.last_input = U_pred[0]
            elif not status_sol['success']:
                rospy.loginfo('============ TRACKING: MPC not feasible ============')
                self.last_input = np.zeros(self.n_u)
                Z_pred = np.zeros((self.N+1, self.n_x))
                U_pred = np.zeros((self.N, self.n_u))
            else:
                rospy.loginfo('============ TRACKING: Applying MPC control ============')
                ecu_msg.servo = U_pred[0,0]
                ecu_msg.motor = U_pred[0,1]
                self.last_input = U_pred[0]

            self.ecu_pub.publish(ecu_msg)

            self.state_prediction = Z_pred
            self.input_prediction = U_pred

            pred_msg = Prediction()
            pred_msg.x = Z_pred[:,0]
            pred_msg.y = Z_pred[:,1]
            pred_msg.psi = Z_pred[:,2]
            pred_msg.v = Z_pred[:,3]
            pred_msg.df = U_pred[:,0]
            pred_msg.a = U_pred[:,1]
            self.pred_pub.publish(pred_msg)

            if self.task_start:
                counter += 1

            self.rate.sleep()