Exemplo n.º 1
0
    def __init__(self):

        MSP_Parser.__init__(self)

        self.altitude = 0
        self.heading = 0

        self.over_water = False
    def __init__(self):

        MSP_Parser.__init__(self)

        self.altitude = 0
        self.heading = 0

        self.over_water = False
Exemplo n.º 3
0
THROTTLE_INC          = .001
CHANNEL_NEUTRAL       = 1500

from msppg import MSP_Parser as Parser
import serial
import time
from sys import argv
import threading

if len(argv) < 2:

    print('Usage: python %s PORT' % argv[0])
    print('Example: python %s /dev/ttyUSB0' % argv[0])
    exit(1)

parser = Parser()
port = serial.Serial(argv[1], BAUD)

# This thread sethe throttle based on incoming messages
class SetterThread(threading.Thread):

    def __init__(self, getter):

        threading.Thread.__init__(self, target=self.setter)

        self.setDaemon(True)

        self.getter = getter

    def setter(self):
Exemplo n.º 4
0
from msppg import MSP_Parser as Parser, serialize_ATTITUDE_RADIANS_Request
import serial

from sys import argv


def handler(pitch, roll, yaw):

    print(pitch, roll, yaw)
    port.write(request)


if __name__ == '__main__':

    parser = Parser()
    request = serialize_ATTITUDE_RADIANS_Request()
    port = serial.Serial(PORT, BAUD)

    parser.set_ATTITUDE_RADIANS_Handler(handler)

    port.write(request)

    while True:

        try:

            parser.parse(port.read(1))

        except KeyboardInterrupt:
Exemplo n.º 5
0
    def __init__(self):

        # No communications or arming yet
        self.comms = None
        self.armed = False

        # Do basic Tk initialization
        self.root = Tk()
        self.root.configure(bg=BACKGROUND_COLOR)
        self.root.resizable(False, False)
        self.root.title('Hackflight Ground Control Station')
        left = (self.root.winfo_screenwidth() - DISPLAY_WIDTH) / 2
        top = (self.root.winfo_screenheight() - DISPLAY_HEIGHT) / 2
        self.root.geometry('%dx%d+%d+%d' % (DISPLAY_WIDTH, DISPLAY_HEIGHT, left, top))
        self.frame = Frame(self.root)

        self.root.wm_iconbitmap(bitmap = "@media/icon.xbm")
        
        self.root.tk.call('wm', 'iconphoto', self.root._w, PhotoImage('icon.png'))

        self.root.protocol('WM_DELETE_WINDOW', self.quit)

        # Create panes for two rows of widgets
        self.pane1 = self._add_pane()
        self.pane2 = self._add_pane()

        # Add a buttons
        self.button_connect = self._add_button('Connect', self.pane1, self._connect_callback)
        self.button_setup  = self._add_button('Setup',  self.pane2, self._setup_callback)
        self.button_motors = self._add_button('Motors', self.pane2, self._motors_button_callback)
        self.button_receiver = self._add_button('Receiver', self.pane2, self._receiver_button_callback)
        self.button_messages = self._add_button('Messages', self.pane2, self._messages_button_callback)
        #self.button_maps = self._add_button('Maps', self.pane2, self._maps_button_callback, disabled=False)

        # Prepare for adding ports as they are detected by our timer task
        self.portsvar = StringVar(self.root)
        self.portsmenu = None
        self.connected = False
        self.ports = []

        # Finalize Tk stuff
        self.frame.pack()
        self.canvas = Canvas(self.root, width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT, background='black')
        self.canvas.pack()

        # Add widgets for motor-testing dialog; hide them immediately
        self.motors = Motors(self)
        self.motors.stop()

        # Create receiver dialog
        self.receiver = Receiver(self)

        # Create messages dialog
        self.messages = Messages(self)

        # Create setup dialog
        self.setup = Setup(self)
        self._schedule_connection_task()

        # Create a maps dialog
        #self.maps = Maps(self, yoffset=-30)

        # Create a splash image
        self.splashimage = PhotoImage(file='media/splash.png')
        self._show_splash()

        # Create a message parser 
        self.parser = MSP_Parser()

        # Set up parser's request strings
        self.attitude_request = self.parser.serialize_ATTITUDE_Request()
        self.rc_request = self.parser.serialize_RC_Request()

        # No messages yet
        self.yaw_pitch_roll = 0,0,0
        self.rxchannels = 0,0,0,0,0

        # A hack to support display in Setup dialog
        self.active_axis = 0
Exemplo n.º 6
0
class GCS:

    def __init__(self):

        # No communications or arming yet
        self.comms = None
        self.armed = False

        # Do basic Tk initialization
        self.root = Tk()
        self.root.configure(bg=BACKGROUND_COLOR)
        self.root.resizable(False, False)
        self.root.title('Hackflight Ground Control Station')
        left = (self.root.winfo_screenwidth() - DISPLAY_WIDTH) / 2
        top = (self.root.winfo_screenheight() - DISPLAY_HEIGHT) / 2
        self.root.geometry('%dx%d+%d+%d' % (DISPLAY_WIDTH, DISPLAY_HEIGHT, left, top))
        self.frame = Frame(self.root)

        self.root.wm_iconbitmap(bitmap = "@media/icon.xbm")
        
        self.root.tk.call('wm', 'iconphoto', self.root._w, PhotoImage('icon.png'))

        self.root.protocol('WM_DELETE_WINDOW', self.quit)

        # Create panes for two rows of widgets
        self.pane1 = self._add_pane()
        self.pane2 = self._add_pane()

        # Add a buttons
        self.button_connect = self._add_button('Connect', self.pane1, self._connect_callback)
        self.button_setup  = self._add_button('Setup',  self.pane2, self._setup_callback)
        self.button_motors = self._add_button('Motors', self.pane2, self._motors_button_callback)
        self.button_receiver = self._add_button('Receiver', self.pane2, self._receiver_button_callback)
        self.button_messages = self._add_button('Messages', self.pane2, self._messages_button_callback)
        #self.button_maps = self._add_button('Maps', self.pane2, self._maps_button_callback, disabled=False)

        # Prepare for adding ports as they are detected by our timer task
        self.portsvar = StringVar(self.root)
        self.portsmenu = None
        self.connected = False
        self.ports = []

        # Finalize Tk stuff
        self.frame.pack()
        self.canvas = Canvas(self.root, width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT, background='black')
        self.canvas.pack()

        # Add widgets for motor-testing dialog; hide them immediately
        self.motors = Motors(self)
        self.motors.stop()

        # Create receiver dialog
        self.receiver = Receiver(self)

        # Create messages dialog
        self.messages = Messages(self)

        # Create setup dialog
        self.setup = Setup(self)
        self._schedule_connection_task()

        # Create a maps dialog
        #self.maps = Maps(self, yoffset=-30)

        # Create a splash image
        self.splashimage = PhotoImage(file='media/splash.png')
        self._show_splash()

        # Create a message parser 
        self.parser = MSP_Parser()

        # Set up parser's request strings
        self.attitude_request = self.parser.serialize_ATTITUDE_Request()
        self.rc_request = self.parser.serialize_RC_Request()

        # No messages yet
        self.yaw_pitch_roll = 0,0,0
        self.rxchannels = 0,0,0,0,0

        # A hack to support display in Setup dialog
        self.active_axis = 0


    def quit(self):
        self.motors.stop()
        self.root.destroy()


    def hide(self, widget):

        widget.place(x=-9999)

    def getChannels(self):

        return self.rxchannels

    def getYawPitchRoll(self):

        # configure button to show connected
        self._enable_buttons()
        self.button_connect['text'] = 'Disconnect'
        self._enable_button(self.button_connect)

        return self.yaw_pitch_roll

    def checkArmed(self):

        if self.armed:

            self._show_armed(self.root)
            self._show_armed(self.pane1)
            self._show_armed(self.pane2)

            self._disable_button(self.button_motors)

        else:

            self._show_disarmed(self.root)
            self._show_disarmed(self.pane1)
            self._show_disarmed(self.pane2)

    def scheduleTask(self, delay_msec, task):

        self.root.after(delay_msec, task)

    def _add_pane(self):

        pane = PanedWindow(self.frame, bg=BACKGROUND_COLOR)
        pane.pack(fill=BOTH, expand=1)
        return pane

    def _add_button(self, label, parent, callback, disabled=True):

        button = Button(parent, text=label, command=callback)
        button.pack(side=LEFT)
        button.config(state = 'disabled' if disabled else 'normal')
        return button

    # Callback for Setup button
    def _setup_callback(self):

        self._clear()

        self.motors.stop()
        self.receiver.stop()
        self.messages.stop()
        #self.maps.stop()

        self.parser.set_ATTITUDE_Handler(self._handle_attitude)
        self.setup.start()

    def _start(self):

        self.parser.set_ATTITUDE_Handler(self._handle_attitude)
        self._send_attitude_request()
        self.setup.start()

        self.parser.set_RC_Handler(self._handle_rc)
        self._send_rc_request()

    # Sends Attitude request to FC
    def _send_attitude_request(self):

        self.comms.send_request(self.attitude_request)

    # Sends RC request to FC
    def _send_rc_request(self):

        self.comms.send_request(self.rc_request)

    # Callback for Motors button
    def _motors_button_callback(self):

        self._clear()

        self.setup.stop()
        self.parser.set_ATTITUDE_Handler(self._handle_attitude)
        self.receiver.stop()
        self.messages.stop()
        #self.maps.stop()
        self.motors.start()

    def _clear(self):

        self.canvas.delete(ALL)

    # Callback for Receiver button
    def _receiver_button_callback(self):

        self._clear()

        self.setup.stop()
        self.motors.stop()
        self.messages.stop()
        #self.maps.stop()

        self.receiver.start()

    # Callback for Messages button
    def _messages_button_callback(self):

        self._clear()

        self.setup.stop()
        self.motors.stop()
        #self.maps.stop()
        self.receiver.stop()

        self.messages.start()

    def _getting_messages(self):

        return self.button_connect['text'] == 'Disconnect'

    # Callback for Maps button
    def _maps_button_callback(self):

        self._clear()

        if self._getting_messages():

            self.receiver.stop()
            self.messages.stop()
            self.setup.stop()
            self.motors.stop()

        #self.maps.start()

    # Callback for Connect / Disconnect button
    def _connect_callback(self):

        if self.connected:

            self.setup.stop()
            #self.maps.stop()
            self.motors.stop()
            self.messages.stop()
            self.receiver.stop()

            if not self.comms is None:

                self.comms.stop()

            self._clear()

            self._disable_buttons()

            self.button_connect['text'] = 'Connect'

            self._show_splash()

        else:

            #self.maps.stop()

            self.comms = Comms(self)
            self.comms.start()

            self.button_connect['text'] = 'Connecting ...'
            self._disable_button(self.button_connect)

            self._hide_splash()

            self.scheduleTask(CONNECTION_DELAY_MSEC, self._start)

        self.connected = not self.connected

    # Gets available ports
    def _getports(self):

        allports = comports()

        ports = []

        for port in allports:
            
            portname = port[0]

            if 'ttyACM' in portname or 'ttyUSB' in portname or 'COM' in portname:
                ports.append(portname)

        return ports

    # Checks for changes in port status (hot-plugging USB cables)
    def _connection_task(self):

        ports = self._getports()

        if ports != self.ports:

            if self.portsmenu is None:

                self.portsmenu = OptionMenu(self.pane1, self.portsvar, *ports)

            else:

                for port in ports:

                    self.portsmenu['menu'].add_command(label=port)

            self.portsmenu.pack(side=LEFT)

            if ports == []:

                self._disable_button(self.button_connect)
                self._disable_buttons()

            else:
                self.portsvar.set(ports[0]) # default value
                self._enable_button(self.button_connect)

            self.ports = ports

        self._schedule_connection_task()

    # Mutually recursive with above
    def _schedule_connection_task(self):

        self.root.after(USB_UPDATE_MSEC, self._connection_task)

    def _disable_buttons(self):

        self._disable_button(self.button_setup)
        self._disable_button(self.button_motors)
        self._disable_button(self.button_receiver)
        self._disable_button(self.button_messages)

    def _enable_buttons(self):

        self._enable_button(self.button_setup)
        self._enable_button(self.button_motors)
        self._enable_button(self.button_receiver)
        self._enable_button(self.button_messages)

    def _enable_button(self, button):

        button['state'] = 'normal'

    def _disable_button(self, button):

        button['state'] = 'disabled'

    def sendMotorMessage(self, index, value):

        values = [1000]*4
        values[index-1] = value
        self.comms.send_message(self.parser.serialize_SET_MOTOR, values)

    def _show_splash(self):

        self.splash = self.canvas.create_image((400,250), image=self.splashimage)

    def _hide_splash(self):

        self.canvas.delete(self.splash)


    def _show_armed(self, widget):

        widget.configure(bg='red')

    def _show_disarmed(self, widget):

        widget.configure(bg=BACKGROUND_COLOR)

        if self._getting_messages():

            self._enable_button(self.button_motors)

    def _handle_calibrate_response(self):

        self.setup.showCalibrated()

    def _handle_params_response(self, pitchroll_kp_percent, yaw_kp_percent):

        # Only handle parms from firmware on a fresh connection
        if self.newconnect:

            self.setup.setParams(pitchroll_kp_percent, yaw_kp_percent)

        self.newconnect = False

    def _handle_attitude(self, x, y, z):

        self.yaw_pitch_roll = z, -y/10., x/10.

        self.messages.setCurrentMessage('Yaw/Pitch/Roll: %+3.3f %+3.3f %+3.3f' % self.yaw_pitch_roll)

        # As soon as we handle the callback from one request, send another request
        self._send_attitude_request()

    def _handle_rc(self, c1, c2, c3, c4, c5, c6, c7, c8):

        self.rxchannels = c1, c2, c3, c4, c5

        # As soon as we handle the callback from one request, send another request
        self._send_rc_request()

        self.messages.setCurrentMessage('Receiver: %04d %04d %04d %04d %04d' % (c1, c2, c3, c4, c5))

    def _handle_arm_status(self, armed):

        self.armed = armed

        self.messages.setCurrentMessage('ArmStatus: %s' % ('ARMED' if armed else 'Disarmed'))

    def _handle_battery_status(self, volts, amps):

        self.messages.setCurrentMessage('BatteryStatus: %3.3f volts, %3.3f amps' % (volts, amps))
Exemplo n.º 7
0
'''

BAUD = 115200

from msppg import MSP_Parser as Parser, serialize_RC_Request
import serial

from sys import argv

if len(argv) < 2:

    print('Usage: python3 %s PORT' % argv[0])
    print('Example: python3 %s /dev/ttyUSB0' % argv[0])
    exit(1)

parser = Parser()
request = serialize_RC_Request()
port = serial.Serial(argv[1], BAUD)

def handler(c1, c2, c3, c4, c5, c6, c7, c8):

    print(c1, c2, c3, c4, c5)
    port.write(request)

parser.set_RC_Handler(handler)

port.write(request)

while True:

    try:
Exemplo n.º 8
0
but WITHOUT ANY WARRANTY without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU Lesser General Public License 
along with this code.  If not, see <http:#www.gnu.org/licenses/>.
'''

BD_ADDR = '00:06:66:73:E3:E8'
BD_PORT = 1

from msppg import MSP_Parser as Parser, serialize_STATE_Request
import bluetooth
from time import time, sleep

parser = Parser()
request = serialize_STATE_Request()

sock = bluetooth.BluetoothSocket(bluetooth.RFCOMM)
sock.connect((BD_ADDR, BD_PORT))

print('connected to ' + BD_ADDR)


def handler(altitude, variometer, positionX, positionY, heading,
            velocityForward, velocityRightward):

    print(altitude, variometer, positionX, positionY, heading, velocityForward,
          velocityRightward)
    sock.send(request)
Exemplo n.º 9
0
along with this code.  If not, see <http:#www.gnu.org/licenses/>.
'''

PORT = '/dev/ttyACM0'

import serial
from msppg import MSP_Parser


def handler(agl, flowx, flowy):
    print(agl, flowx, flowy)


port = serial.Serial(PORT, 115200)

parser = MSP_Parser()
parser.set_RANGE_AND_FLOW_Handler(handler)

while True:

    c = None

    try:

        c = port.read()

    except KeyboardInterrupt:

        port.close()
        break
Exemplo n.º 10
0
'''

BAUD = 115200

from msppg import MSP_Parser as Parser
import serial

from sys import argv

if len(argv) < 2:

    print('Usage: python %s PORT' % argv[0])
    print('Example: python %s /dev/ttyUSB0' % argv[0])
    exit(1)

parser = Parser()
request = parser.serialize_ATTITUDE_Request()
port = serial.Serial(argv[1], BAUD)

def handler(pitch, roll, yaw):

    print(pitch, roll, yaw)
    port.write(request)

parser.set_ATTITUDE_Handler(handler)

port.write(request)

while True:

    try:
Exemplo n.º 11
0
'''

BAUD = 115200

from msppg import MSP_Parser as Parser, serialize_ATTITUDE_Request
import serial

from sys import argv

if len(argv) < 2:

    print('Usage: python3 %s PORT' % argv[0])
    print('Example: python3 %s /dev/ttyUSB0' % argv[0])
    exit(1)

parser = Parser()
request = serialize_ATTITUDE_Request()
port = serial.Serial(argv[1], BAUD)

def handler(pitch, roll, yaw):

    print(pitch, roll, yaw)
    port.write(request)

parser.set_ATTITUDE_Handler(handler)

port.write(request)

while True:

    try:
Exemplo n.º 12
0
#PORT = 'COM13'          # Windows
PORT = '/dev/ttyACM0'  # Linux

from msppg import MSP_Parser as Parser, serialize_LOITER_Request
import serial


def handler(agl, flowx, flowy):

    print(agl, flowx, flowy)
    port.write(request)


if __name__ == '__main__':

    parser = Parser()
    request = serialize_LOITER_Request()
    port = serial.Serial(PORT, BAUD)

    parser.set_LOITER_Handler(handler)

    port.write(request)

    while True:

        try:

            parser.parse(port.read(1))

        except KeyboardInterrupt:
Exemplo n.º 13
0
    def __init__(self):

        MSP_Parser.__init__(self)

        self.altitude = 0
        self.heading = 0
Exemplo n.º 14
0
CHANNEL_NEUTRAL = 1500
CHANNEL_AUTOPILOT = 1600

from msppg import MSP_Parser as Parser, serialize_SET_RAW_RC, serialize_RC_Request
import serial
import time
from sys import argv
import threading

if len(argv) < 2:

    print('Usage: python3 %s PORT' % argv[0])
    print('Example: python3 %s /dev/ttyUSB0' % argv[0])
    exit(1)

parser = Parser()
port = serial.Serial(argv[1], BAUD)


# This thread sethe throttle based on incoming messages
class SetterThread(threading.Thread):
    def __init__(self, getter):

        threading.Thread.__init__(self, target=self.setter)

        self.setDaemon(True)

        self.getter = getter

    def setter(self):