示例#1
0
 def update_wps(self, wp_list):
     if Settings.enable_autopilot:
         if len(wp_list) < 2:
             return
         with self.wp_update_in_progress:
             if LosSettings.enable_los:
                 if self.los_thread.isAlive():
                     self.los_restart_event.set()
                     self.los_stop_event.set()
                     self.los_thread.join()
                     self.los_stop_event.clear()
                     self.los_restart_event.clear()
                 self.los_controller.update_wps(wp_list)
                 self.los_controller.update_pos(self.cur_pos_msg)
                 self.los_thread = threading.Thread(
                     target=self.los_controller.loop, daemon=True)
                 self.los_thread.start()
                 self.los_start_event.set()
                 return
             thread = self.stop_autopilot()
             thread.join()
             self.send_autopilot_msg(ap.Command(
                 ap.CommandOptions.CLEAR_WPS))
             self.send_autopilot_msg(ap.AddWaypoints(wp_list))
             self.switch_ap_mode(ap.GuidanceModeOptions.PATH_FOLLOWING)
             # self.send_autopilot_msg(ap.Setpoint(0, ap.Dofs.YAW, False))
             # if len(wp_list[0]) > 3:
             #     self.send_autopilot_msg(ap.TrackingSpeed(wp_list[0][3]))
             # else:
             self.send_autopilot_msg(
                 ap.TrackingSpeed(CollisionSettings.tracking_speed))
示例#2
0
 def get_pos(self):
     if not self.ask_for_desired:
         self.send_autopilot_msg(ap.GetMessage(ap.MsgType.ROV_STATE))
     else:
         self.send_autopilot_msg(
             ap.GetMessage(
                 [ap.MsgType.ROV_STATE, ap.MsgType.ROV_STATE_DESIRED]))
示例#3
0
 def close(self):
     if Settings.enable_autopilot:
         if LosSettings.enable_los:
             self.los_stop_event.set()
         if CollisionSettings.send_new_wps and self.in_control:
             logger.info('Shutting down autopilot')
             self.ask_for_desired = True
             thread = self.stop_autopilot()
             thread.join()
             logger.info(
                 'In stationkeeping mode. Waiting for small errors.')
             state_error = None
             self.ap_pos_received.clear()
             while state_error is None or not state_error.is_small(
                     LosSettings.enable_los):
                 self.ap_pos_received.wait()
                 if self.cur_desired_pos_msg is None or self.cur_pos_msg is None:
                     self.ap_pos_received.clear()
                     continue
                 state_error = self.cur_pos_msg - self.cur_desired_pos_msg
             # All errors are small
             self.send_autopilot_msg(ap.RemoteControlRequest(False))
             logger.info('Released control of autopilot')
         if CollisionSettings.send_new_wps:
             self.autopilot_watchdog_stop_event.set()
示例#4
0
 def set_speed(self, speed):
     if speed != self.surge_speed:
         self.surge_speed = speed
         if Settings.input_source == 0:
             self.msg_client.send_autopilot_msg(ap.CruiseSpeed(speed))
         else:
             self.msg_client.send_msg('vel_com', speed)
         logger.info('Surge speed adjusted to {:.2f} m/s'.format(speed))
示例#5
0
 def stop_and_turn(self, theta):
     if Settings.enable_autopilot:
         logger.info('Stop and turn {:.2f} deg'.format(theta * 180.0 /
                                                       np.pi))
         if LosSettings.enable_los:
             if self.los_thread.isAlive():
                 self.los_stop_event.set()
                 self.los_thread.join()
                 self.los_stop_event.clear()
         else:
             self.stop_autopilot()
         self.send_autopilot_msg(
             ap.Setpoint(theta + self.cur_pos_msg.yaw, ap.Dofs.YAW, True))
示例#6
0
 def ping_autopilot_server(self):
     # Get empty msg to keep control
     if self.autopilot_sid == 0:
         # self.send_autopilot_msg(ap.ControllerOptions([]))
         self.send_autopilot_msg(ap.RemoteControlRequest(True))
         logger.info("Asked for remote control")
         return False
     else:
         self.in_control = True
         if Settings.pos_msg_source == 1:
             # self.send_autopilot_msg(ap.ControllerOptions([ap.Dofs.SURGE, ap.Dofs.SWAY, ap.Dofs.HEAVE, ap.Dofs.YAW]))
             self.autopilot_watchdog_stop_event.set()
             self.switch_ap_mode(ap.GuidanceModeOptions.STATION_KEEPING)
             # while self.cur_pos_msg is None:
             #     pass
             # self.send_autopilot_msg(ap.Setpoint(self.cur_pos_msg.lat, ap.Dofs.SURGE, True))
             # self.send_autopilot_msg(ap.Setpoint(self.cur_pos_msg.long, ap.Dofs.SWAY, True))
             # self.send_autopilot_msg(ap.Setpoint(self.cur_pos_msg.yaw, ap.Dofs.YAW, True))
             # self.send_autopilot_msg(ap.VerticalPos(ap.VerticalPosOptions.ALTITUDE, 10))
         else:
             self.send_autopilot_msg(ap.GetMessage(
                 ap.MsgType.EMPTY_MESSAGE))
         return True
示例#7
0
 def stop_autopilot(self):
     if Settings.enable_autopilot:
         logger.info('Stopping ROV')
         if self.cur_pos_msg is None:
             return
         if self.guidance_mode is not ap.GuidanceModeOptions.STATION_KEEPING:
             if self.guidance_mode is ap.GuidanceModeOptions.PATH_FOLLOWING:
                 # self.switch_ap_mode(ap.GuidanceModeOptions.PATH_FOLLOWING))
                 self.send_autopilot_msg(ap.TrackingSpeed(0))
             if self.guidance_mode is ap.GuidanceModeOptions.CRUISE_MODE:
                 self.send_autopilot_msg(ap.CruiseSpeed(0))
             counter = 0
             n_set = 1
             max = 20
             surge = np.ones(max)
             surge[0] = self.cur_pos_msg.v_surge
             acc = 1
             while abs(np.sum(surge) / n_set) > 0.02:
                 # print(np.sum(v_surge)/n_set, acc)
                 self.ap_pos_received.clear()
                 self.ap_pos_received.wait(0.1)
                 counter += 1
                 if counter == max:
                     counter = 0
                 surge[counter] = self.cur_pos_msg.v_surge
                 acc = abs((surge[counter] - surge[counter - 1]) / 0.1)
                 if n_set < max:
                     n_set += 1
             self.switch_ap_mode(ap.GuidanceModeOptions.STATION_KEEPING)
             # self.send_autopilot_msg(ap.Setpoint(0, ap.Dofs.SURGE, True))
             # self.send_autopilot_msg(ap.Setpoint(0, ap.Dofs.SWAY, True))
             # self.send_autopilot_msg(ap.Setpoint(self.cur_pos_msg.yaw, ap.Dofs.YAW, True))
             self.send_autopilot_msg(
                 ap.VerticalPos(ap.VerticalPosOptions.ALTITUDE,
                                self.cur_pos_msg.alt))
         else:
             return
示例#8
0
 def switch_ap_mode(self, mode):
     if Settings.enable_autopilot:
         if self.guidance_mode is not mode:
             self.guidance_mode = mode
             logger.info('Switching to {}'.format(mode.name))
             self.send_autopilot_msg(ap.GuidanceMode(mode))
示例#9
0
def handler_factory(callback):
    def createHandler(*args, **keys):
        return Handler(callback, *args, **keys)

    return createHandler


if __name__ == '__main__':
    from time import sleep
    from settings import ConnectionSettings
    client = UdpClient(ConnectionSettings.sonar_port,
                       ConnectionSettings.pos_port,
                       ConnectionSettings.autopilot_ip,
                       ConnectionSettings.autopilot_server_port,
                       ConnectionSettings.autopilot_listen_port)
    client.start()
    while not client.in_control:
        pass
    client.switch_ap_mode(ap.GuidanceModeOptions.CRUISE_MODE)
    client.send_autopilot_msg(ap.CruiseSpeed(0.2))
    # counter = 0
    # while counter < 4:
    #     sleep(5)
    #     client.send_autopilot_msg(ap.Setpoint(counter*np.pi/4, ap.Dofs.YAW, True))
    #     counter += 1
    sleep(5)
    print('closing down')
    client.close()
    print('closed')
示例#10
0
    def loop(self):
        logger.info('New path received')
        if len(self.wp_list) < 2 or self.pos_msg is None:
            logger.info('To few waypoints. Returning to Stationkeeping.')
            self.msg_client.stop_autopilot()
            return

        if LosSettings.log_paths:
            chi_log = []
            surge_log = []
            timestamp = []
            delta_log = []
            e_log = []
            wp_change = []
            roa_log = []
            slow_down_dist_log = []
            slown_down_vel_log = []
            pos_log = []

        # self.surge_speed = 0
        # Initial check
        pos_msg, wp_list, wp_counter, wp_grad, segment_lengths = self.get_info(
        )
        chi, delta, e = self.get_los_values(wp_list[0], wp_list[1], pos_msg)
        start_chi = wrapToPi(get_angle(wp_list[0], wp_list[1]))
        logger.info('Start Chi: {:.2f}'.format(start_chi * 180.0 / np.pi))
        # TODO: CHeck if on initial path
        if (segment_length(wp_list[0], (pos_msg.north, pos_msg.east)) > LosSettings.roa or
                abs(start_chi - pos_msg.yaw) > LosSettings.start_heading_diff) and \
                not (segment_lengths[0] - delta > 0 and abs(e) < LosSettings.roa):
            logger.info(
                'Not on path, s: {:.2f}, e: {:.2f}, d_psi: {:.2f}'.format(
                    segment_lengths[0] - delta, e,
                    (start_chi - pos_msg.yaw) * 180.0 / np.pi))
            # Wait for low speed before stationkeeping
            # logger.info('Speed to high to start LOS-guidance')
            # self.set_speed(0)
            # while self.start_event.wait() and not self.stopped_event.isSet():
            #     pos_msg = self.get_pos()
            #     if pos_msg.v_surge < 0.01:
            #         break
            th = self.msg_client.stop_autopilot()
            th.join()
            # self.msg_client.switch_ap_mode(ap.GuidanceModeOptions.STATION_KEEPING)
            if Settings.input_source == 0:
                self.msg_client.send_autopilot_msg(
                    ap.Setpoint(wp_list[0][0], ap.Dofs.NORTH, True))
                self.msg_client.send_autopilot_msg(
                    ap.Setpoint(wp_list[0][1], ap.Dofs.EAST, True))
                self.msg_client.send_autopilot_msg(
                    ap.Setpoint(wp_list[0][2], ap.Dofs.DEPTH, True))
                self.msg_client.send_autopilot_msg(
                    ap.Setpoint(start_chi, ap.Dofs.YAW, True))
            else:
                self.msg_client.send_msg('north_com', wp_list[0][0])
                self.msg_client.send_msg('east_com', wp_list[0][1])
                self.msg_client.send_msg('depth_com', wp_list[0][2])
                self.msg_client.send_msg('yaw_com', start_chi)
            # logger.info('To far from inital setpoint. Moving to: '
            #             '[N={:.6f}, E={:.6f}, D={:.2f}, YAW={:.2f} deg]'.format(wp_list[0][0], wp_list[0][1],
            #                                                       wp_list[0][2], start_chi*180.0/np.pi))
            logger.info(
                'To far from inital setpoint. Yaw_hat:{:.2f}, north_hat: {:.2f}, east_hat: {:.2f}'
                .format((start_chi - pos_msg.yaw) * 180.0 / np.pi,
                        wp_list[0][0] - pos_msg.north,
                        wp_list[0][1] - pos_msg.east))

            while self.start_event.wait() and not self.stopped_event.isSet() and \
                    (segment_length(wp_list[0], (pos_msg.north, pos_msg.east)) > 1 or
                            abs(start_chi - pos_msg.yaw) > LosSettings.start_heading_diff):
                pos_msg = self.get_pos()

        if Settings.input_source == 0:
            self.msg_client.switch_ap_mode(ap.GuidanceModeOptions.CRUISE_MODE)
        # self.set_speed(self.normal_surge_speed)
        turn_speed, slow_down_dist = self.turn_vel(0)
        if segment_lengths[wp_counter] < LosSettings.roa:
            self.roa = segment_lengths[wp_counter] / 2
        else:
            self.roa = LosSettings.roa
        if LosSettings.log_paths:
            roa_log.append(self.roa)
            slow_down_dist_log.append(slow_down_dist)
            slown_down_vel_log.append(turn_speed)
        # logger.info('Setting cruise speed: {} m/s'.format(self.surge_speed))
        if Settings.input_source == 0:
            self.msg_client.send_autopilot_msg(
                ap.Setpoint(wp_list[0][2], ap.Dofs.DEPTH, True))
            self.msg_client.send_autopilot_msg(
                ap.Setpoint(chi, ap.Dofs.YAW, True))
        else:
            self.msg_client.send_msg('depth_com', wp_list[0][2])
            self.msg_client.send_msg('yaw_com', wrapToPi(chi))
        if (slow_down_dist < 0) or (delta <= slow_down_dist):
            self.set_speed(turn_speed)
        else:
            self.set_speed(self.normal_surge_speed)
        if LosSettings.log_paths:
            chi_log.append(chi)
            surge_log.append(self.surge_speed)
            timestamp.append(datetime.now().strftime("%H:%M:%S"))
            delta_log.append(delta)
            e_log.append(e)
            wp_change.append(datetime.now().strftime("%H:%M:%S"))
            pos_log.append(pos_msg.to_tuple())
        logger.info('Path Started')
        while not self.stopped_event.isSet() and self.start_event.wait(
        ) and self.wp_counter < len(self.wp_list):
            pos_msg = self.get_pos()

            # Get new setpoint
            chi, delta, e = self.get_los_values(wp_list[wp_counter],
                                                wp_list[wp_counter + 1],
                                                pos_msg)

            # # Check if slow down
            # if slow_down_dist >= 0 and delta <= slow_down_dist:
            #     self.set_speed(turn_speed)

            # Check if ROA
            if delta < self.roa:
                wp_counter += 1
                if LosSettings.log_paths:
                    wp_change.append(datetime.now().strftime("%H:%M:%S"))
                try:
                    turn_speed, slow_down_dist = self.turn_vel(wp_counter)
                    if segment_lengths[wp_counter] < LosSettings.roa:
                        self.roa = segment_lengths[wp_counter] / 2
                    else:
                        self.roa = LosSettings.roa
                    if LosSettings.log_paths:
                        roa_log.append(self.roa)
                        slow_down_dist_log.append(slow_down_dist)
                        slown_down_vel_log.append(turn_speed)
                    if Settings.input_source == 0:
                        self.msg_client.send_autopilot_msg(
                            ap.Setpoint(wp_list[wp_counter + 1][2],
                                        ap.Dofs.DEPTH, True))
                    else:
                        self.msg_client.send_msg('alt_com', 2.0)
                    chi, delta, e = self.get_los_values(
                        wp_list[wp_counter], wp_list[wp_counter + 1], pos_msg)
                except IndexError:
                    logger.info('Final Waypoint reached!')
                    break
                logger.info(
                    'Current wp is WP{}: [N={:.6f}, E={:.6f}, D={:.2f}], ROA={:.2f}'
                    .format(wp_counter, wp_list[wp_counter][0],
                            wp_list[wp_counter][1], wp_list[wp_counter][2],
                            self.roa))

            # Check if slow down
            if (slow_down_dist < 0) or (delta <= slow_down_dist):
                self.set_speed(turn_speed)
            else:
                self.set_speed(self.normal_surge_speed)

            # Send new setpoints
            if abs(chi - self.last_chi) > LosSettings.send_new_heading_limit:
                # logger.info('Chi: {:2f}'.format(wrapToPi(chi)*180.0/np.pi))
                if Settings.input_source == 0:
                    self.msg_client.send_autopilot_msg(
                        ap.Setpoint(wrapToPi(chi), ap.Dofs.YAW, True))
                else:
                    self.msg_client.send_msg('yaw_com', wrapToPi(chi))
                self.last_chi = chi
            if LosSettings.log_paths:
                chi_log.append(chi)
                surge_log.append(self.surge_speed)
                timestamp.append(datetime.now().strftime("%H:%M:%S"))
                delta_log.append(delta)
                e_log.append(e)
                pos_log.append(pos_msg.to_tuple())
            with self.lock:
                self.wp_counter = wp_counter
                self.e = e
                self.delta = delta
        with self.lock:
            self.e = 0
            self.delta = 0
        if not self.restart_event.isSet():
            logger.info('WP loop finished: Stopping ROV')
            self.msg_client.stop_autopilot()
        else:
            logger.info('WP loop finished: Restarting loop')
        if LosSettings.log_paths:
            savemat('{}Los_log_{}'.format(
                Settings.log_folder,
                datetime.now().strftime("%Y%m%d-%H%M%S")),
                    mdict={
                        'chi': np.array(chi_log),
                        'surge': np.array(surge_log),
                        'time': timestamp,
                        'path': wp_list,
                        'delta': np.array(delta_log),
                        'cross_track': np.array(e_log),
                        'slow_down_dist': np.array(slow_down_dist_log),
                        'roa': np.array(roa_log),
                        'slow_down_vel': np.array(slown_down_vel_log),
                        'wp_change': wp_change,
                        'pos': np.array(pos_log)
                    })