Esempio n. 1
0
    def __init__(self):
        super(Autopilot, self).__init__()

        # setup all processes to exit on any signal
        self.childpids = []

        def cleanup(signal_number, frame=None):
            print('got signal', signal_number, 'cleaning up')
            while self.childpids:
                pid = self.childpids.pop()
                #print('kill child', pid)
                os.kill(pid, signal.SIGTERM)  # get backtrace
            sys.stdout.flush()
            if signal_number != 'atexit':
                raise KeyboardInterrupt  # to get backtrace on all processes

        # unfortunately we occasionally get this signal,
        # some sort of timing issue where python doesn't realize the pipe
        # is broken yet, so doesn't raise an exception
        def printpipewarning(signal_number, frame):
            print('got SIGPIPE, ignoring')

        import signal
        for s in range(1, 16):
            if s == 13:
                signal.signal(s, printpipewarning)
            elif s != 9:
                signal.signal(s, cleanup)

#    self.server = SignalKServer()
        self.server = SignalKPipeServer()
        self.boatimu = BoatIMU(self.server)
        self.sensors = Sensors(self.server)
        self.servo = servo.Servo(self.server, self.sensors)

        self.version = self.Register(Value, 'version',
                                     'pypilot' + ' ' + strversion)
        self.heading_command = self.Register(HeadingProperty,
                                             'heading_command', 0)
        self.enabled = self.Register(BooleanProperty, 'enabled', False)
        self.lastenabled = False

        self.lost_mode = self.Register(BooleanValue, 'lost_mode', False)
        self.mode = self.Register(ModeProperty, 'mode')
        self.mode.ap = self
        self.lastmode = False

        self.last_heading = False
        self.last_heading_off = self.boatimu.heading_off.value

        self.pilots = []
        for pilot_type in pilots.default:
            self.pilots.append(pilot_type(self))

        self.pilot = self.Register(EnumProperty,
                                   'pilot',
                                   'basic',
                                   ['simple', 'basic', 'learning', 'wind'],
                                   persistent=True)

        timestamp = self.server.TimeStamp('ap')
        self.heading = self.Register(SensorValue,
                                     'heading',
                                     timestamp,
                                     directional=True)
        self.heading_error = self.Register(SensorValue, 'heading_error',
                                           timestamp)
        self.heading_error_int = self.Register(SensorValue,
                                               'heading_error_int', timestamp)
        self.heading_error_int_time = time.time()

        self.tack = tacking.Tack(self)

        self.gps_compass_offset = HeadingOffset()
        self.gps_speed = self.Register(SensorValue, 'gps_speed', timestamp)

        self.wind_compass_offset = HeadingOffset()
        self.true_wind_compass_offset = HeadingOffset()

        self.wind_direction = self.Register(SensorValue,
                                            'wind_direction',
                                            timestamp,
                                            directional=True)
        self.wind_speed = self.Register(SensorValue, 'wind_speed', timestamp)

        self.runtime = self.Register(TimeValue, 'runtime')  #, persistent=True)

        device = '/dev/watchdog0'
        self.watchdog_device = False
        try:
            self.watchdog_device = open(device, 'w')
        except:
            print('warning: failed to open special file', device,
                  'for writing')
            print('         cannot stroke the watchdog')
        if os.system('sudo chrt -pf 1 %d 2>&1 > /dev/null' % os.getpid()):
            print('warning, failed to make autopilot process realtime')

        self.starttime = time.time()
        self.times = 4 * [0]

        self.childpids = [
            self.boatimu.imu_process.pid, self.boatimu.auto_cal.process.pid,
            self.server.process.pid, self.sensors.nmea.process.pid,
            self.sensors.gps.process.pid
        ]
        signal.signal(signal.SIGCHLD, cleanup)
        import atexit
        atexit.register(lambda: cleanup('atexit'))

        self.lastdata = False
        self.lasttime = time.time()
Esempio n. 2
0
    def __init__(self):
        super(Autopilot, self).__init__()    
        self.watchdog_device = False

        self.server = pypilotServer()
        self.client = pypilotClient(self.server)
        self.boatimu = BoatIMU(self.client)
        self.sensors = Sensors(self.client)
        self.servo = servo.Servo(self.client, self.sensors)
        self.version = self.register(Value, 'version', 'pypilot' + ' ' + strversion)
        self.timestamp = self.client.register(SensorValue('timestamp', 0))
        self.starttime = time.monotonic()
        self.mode = self.register(ModeProperty, 'mode')

        self.preferred_mode = self.register(Value, 'preferred_mode', 'compass')
        self.lastmode = False    
        self.mode.ap = self
        
        self.heading_command = self.register(HeadingProperty, 'heading_command', self.mode)
        self.enabled = self.register(BooleanProperty, 'enabled', False)
        self.lastenabled = False
        
        self.last_heading = False
        self.last_heading_off = self.boatimu.heading_off.value
        
        self.pilots = {}
        for pilot_type in pilots.default:
            try:
                pilot = pilot_type(self)
                self.pilots[pilot.name] = pilot
            except Exception as e:
                print('failed to load pilot', pilot_type, e)

        pilot_names = list(self.pilots)
        print('Loaded Pilots:', pilot_names)
        self.pilot = self.register(EnumProperty, 'pilot', 'basic', pilot_names, persistent=True)

        self.heading = self.register(SensorValue, 'heading', directional=True)
        self.heading_error = self.register(SensorValue, 'heading_error')
        self.heading_error_int = self.register(SensorValue, 'heading_error_int')
        self.heading_error_int_time = time.monotonic()

        self.tack = tacking.Tack(self)

        self.gps_compass_offset = HeadingOffset()
        self.gps_speed = 0

        self.wind_compass_offset = HeadingOffset()
        self.true_wind_compass_offset = HeadingOffset()

        self.wind_direction = self.register(SensorValue, 'wind_direction', directional=True)
        self.wind_speed = 0

        self.runtime = self.register(TimeValue, 'runtime') #, persistent=True)
        self.timings = self.register(SensorValue, 'timings', False)

        device = '/dev/watchdog0'
        try:
            self.watchdog_device = open(device, 'w')
        except:
            print('warning: failed to open special file', device, 'for writing')
            print('         cannot stroke the watchdog')

        self.server.poll() # setup process before we switch main process to realtime
        if os.system('sudo chrt -pf 1 %d 2>&1 > /dev/null' % os.getpid()):
            print('warning, failed to make autopilot process realtime')
    
        self.lasttime = time.monotonic()

        # setup all processes to exit on any signal
        self.childprocesses = [self.boatimu.imu, self.boatimu.auto_cal,
                               self.sensors.nmea, self.sensors.gpsd,
                               self.sensors.signalk, self.server]
        def cleanup(signal_number, frame=None):
            #print('got signal', signal_number, 'cleaning up')
            if signal_number == signal.SIGCHLD:
                pid = os.waitpid(-1, os.WNOHANG)
                #print('sigchld waitpid', pid)

            if signal_number != 'atexit': # don't get this signal again
                signal.signal(signal_number, signal.SIG_IGN)

            while self.childprocesses:
                process = self.childprocesses.pop().process
                if process:
                    pid = process.pid
                    #print('kill', pid, process)
                    try:
                        os.kill(pid, signal.SIGTERM) # get backtrace
                    except Exception as e:
                        pass
                        #print('kill failed', e)
            sys.stdout.flush()
            if signal_number != 'atexit':
                raise KeyboardInterrupt # to get backtrace on all processes

        # unfortunately we occasionally get this signal,
        # some sort of timing issue where python doesn't realize the pipe
        # is broken yet, so doesn't raise an exception
        def printpipewarning(signal_number, frame):
            print('got SIGPIPE, ignoring')

        import signal
        for s in range(1, 16):
            if s == 13:
                signal.signal(s, printpipewarning)
            elif s != 9:
                signal.signal(s, cleanup)

        signal.signal(signal.SIGCHLD, cleanup)
        import atexit
        atexit.register(lambda : cleanup('atexit'))