diff --git a/sw/tools/parrot/bebop.py b/sw/tools/parrot/bebop.py index 178cccea84..10fb56e1ad 100755 --- a/sw/tools/parrot/bebop.py +++ b/sw/tools/parrot/bebop.py @@ -23,18 +23,113 @@ from __future__ import print_function from parrot_utils import ParrotUtils +import re +import argparse +from time import sleep class Bebop(ParrotUtils): uav_name = 'Bebop' address = '192.168.42.1' version_file = '/version.txt' upload_path = '/data/ftp/' + scripts_path = 'internal_000/scripts/' + config_file = upload_path + scripts_path + 'pprz.conf' check_version_before_run = True update_time_before_run = True + # Read from config file + def read_from_config(self, name): + self.config_content = self.execute_command('cat ' + self.config_file) + + # Search for the name + search = re.search(name + '=([^\r\n\t ]+)',self.config_content) + if search is None: + return 'Unknown' + else: + return search.group(1) + + # Write to config + def write_to_config(self, name, value): + if self.read_from_config(name) == 'Unknown': + self.execute_command('echo "' + name + '=' + value + '\" >> ' + self.config_file) + else: + self.execute_command('sed -i "s/\(' + name + ' *= *\).*/\\1' + value + '/g" ' + self.config_file) + def uav_status(self): print('Parrot version:\t\t' + str(self.check_version())) + join = {'Unknown': 'No', '0': 'No', '1': 'Yes'} + print('Join Wifi:\t\t' + self.read_from_config('JOIN_WIFI')) + print('Network id:\t\t' + self.read_from_config('WIFI_SSID')) + mode = {'0': 'Master', '1': 'Managed'} + print('Wifi Amode:\t\t' + self.read_from_config('WIFI_AMODE')) + print('Currently running:\t' + self.check_running()) + autorun = {'Unknown': 'Native (autorun not installed)', '0': 'Native', '1': 'Paparazzi'} + print('Autorun at start:\t'+autorun[self.read_from_config('START_PPRZ')]) + def bebop_install_scripts(self): + print('Installing Paparazzi scripts') + self.upload_file('bebop/pprz.conf', self.scripts_path, kill_prog=False) + self.upload_file('bebop/config_network.script', self.scripts_path, kill_prog=False) + self.upload_file('bebop/button_switch', self.scripts_path, kill_prog=False) + self.upload_file('bebop/pprzstarter', self.scripts_path, kill_prog=False) + self.execute_command("mount -o remount,rw /") + self.execute_command("sed -i 's|^exit 0|/data/ftp/internal_000/scripts/pprzstarter \& exit 0|' /etc/init.d/rcS") + self.execute_command("chmod a+x /etc/init.d/rcS") + self.execute_command("chmod a+x /data/ftp/internal_000/scripts/pprzstarter") + self.execute_command("chmod a+x /data/ftp/internal_000/scripts/button_switch") + self.execute_command("chmod a+x /data/ftp/internal_000/scripts/config_network.script") + self.execute_command("dos2unix /data/ftp/internal_000/scripts/pprzstarter") + self.execute_command("dos2unix /data/ftp/internal_000/scripts/button_switch") + self.execute_command("dos2unix /data/ftp/internal_000/scripts/pprz.conf") + self.execute_command("cp /bin/onoffbutton/shortpress_3.sh /bin/onoffbutton/shortpress_3.sh.backup") + self.execute_command("echo '#!/bin/sh' > /bin/onoffbutton/shortpress_3.sh") + self.execute_command("echo '' >> /bin/onoffbutton/shortpress_3.sh") + self.execute_command("echo '/data/ftp/internal_000/scripts/button_switch' >> /bin/onoffbutton/shortpress_3.sh") + + def bebop_uninstall_scripts(self): + print('Uninstalling Paparazzi scripts') + self.execute_command("mount -o remount,rw /") + self.execute_command("sed -i 's|^/data/ftp/internal_000/scripts/pprzstarter \& exit 0|exit 0|' /etc/init.d/rcS") + self.execute_command("chmod a+x /etc/init.d/rcS") + self.execute_command("mv /bin/onoffbutton/shortpress_3.sh.backup /bin/onoffbutton/shortpress_3.sh") + self.execute_command("rm -rf /data/ftp/internal_000/scripts/*") + + def check_autoboot(self): + pprzstarter = self.execute_command('grep "pprzstarter" /etc/init.d/rcS') + if "pprzstarter" in pprzstarter: + return True + else: + return False + + def bebop_set_ssid(self, name): + ''' + Set network SSID (of the router to join, not the Bebop SSID in master mode) + ''' + self.write_to_config('WIFI_SSID', name) + print('The network ID (SSID) to be joined is changed to ' + name) + + def bebop_set_wifi_mode(self, mode): + ''' + Set Wifi mode, master or managed + ''' + mode_id = { 'master': '0', 'managed': '1' } + self.write_to_config('JOIN_WIFI', mode_id[mode]) + print('The Wifi mode is now ' + mode) + + def bebop_shutdown(self): + ''' + Proper bebop shutdown + ''' + print("Shuting down Bebop (restart by hand if needed)") + self.execute_command('/bin/ardrone3_shutdown.sh', timeout=1) + + def reboot(self): + ''' + Custom reboot, in fact a proper shutdown as simple reboot seems too brutal + Restart has to be done by hand + ''' + self.bebop_shutdown() + def init_extra_parser(self): # Parse the extra arguments @@ -43,10 +138,94 @@ class Bebop(ParrotUtils): self.parser.add_argument('--max_version', metavar='MAX', default='4.4.2', help='force maximum version allowed') - def parse_extra_args(self, args): - # nothing here - pass + ss = self.subparsers.add_parser('networkid', help='Set the network ID (SSID) to join in managed mode') + ss.add_argument('name', help='The new network ID (SSID)') + ss = self.subparsers.add_parser('wifimode', help='Set the Wifi mode the Bebop 1 or 2') + ss.add_argument('mode', help='The new Wifi mode', choices=['master', 'managed']) + + ss = self.subparsers.add_parser('configure_network', help='Configure the network on the Bebop 1 or 2') + ss.add_argument('name', help='The network ID (SSID) to join in managed mode') + ss.add_argument('mode', help='The new Wifi mode', choices=['master', 'managed']) + + ss = self.subparsers.add_parser('install_autostart', help='Install custom autostart script and set what to start on boot for the Bebop 1 or 2') + ss.add_argument('type', choices=['native', 'paparazzi'], + help='what to start on boot') + + ss = self.subparsers.add_parser('autostart', help='Set what to start on boot for the Bebop 1 or 2') + ss.add_argument('type', choices=['native', 'paparazzi'], + help='what to start on boot') + + ss = self.subparsers.add_parser('uninstall_autostart', help='Remove custom autostart scripts') + + def parse_extra_args(self, args): + + # Change the network ID + if args.command == 'networkid': + self.bebop_set_ssid(args.name) + if raw_input("Shall I restart the Bebop? (y/N) ").lower() == 'y': + self.reboot() + + # Change the wifi mode + elif args.command == 'wifimode': + self.bebop_set_wifi_mode(args.mode) + if raw_input("Shall I restart the Bebop? (y/N) ").lower() == 'y': + self.reboot() + + # Install and configure network + elif args.command == 'configure_network': + print('=== Current network setup ===') + self.uav_status() + print('=============================') + if self.check_autoboot(): + print('Custom autostart (and network) script already installed') + if raw_input("Shall I reinstall the autostart (and network) script (y/N) ").lower() == 'y': + self.bebop_install_scripts() + else: + print('Custom autostart (and network) script is required but is not installed') + if raw_input("Shall I reinstall the autostart (and network) script (y/N) ").lower() == 'y': + self.bebop_install_scripts() + else: + print('Scripts not installed, Leaving.') + return + sleep(0.5) + self.bebop_set_ssid(args.name) + self.bebop_set_wifi_mode(args.mode) + sleep(0.5) + print('== New network setup after boot ==') + self.uav_status() + print('==================================') + + if raw_input("Shall I restart the Bebop? (y/N) ").lower() == 'y': + self.reboot() + + # Install and configure autostart + elif args.command == 'install_autostart': + if self.check_autoboot(): + print('Custom autostart script already installed') + if raw_input("Shall I reinstall the autostart script (y/N) ").lower() == 'y': + self.bebop_install_scripts() + else: + self.bebop_install_scripts() + autorun = {'native': '0', 'paparazzi': '1'} + self.write_to_config('START_PPRZ', autorun[args.type]) + print('The autostart on boot is changed to ' + args.type) + + if raw_input("Shall I restart the ARDrone 2? (y/N) ").lower() == 'y': + self.reboot() + + # Change the autostart + elif args.command == 'autostart': + autorun = {'native': '0', 'paparazzi': '1'} + self.write_to_config('START_PPRZ', autorun[args.type]) + print('The autostart on boot is changed to ' + args.type) + + # Uninstall autostart + elif args.command == 'uninstall_autostart': + if self.check_autoboot(): + self.bebop_uninstall_scripts() + else: + print("Autostart script not found") if __name__ == "__main__": bebop = Bebop() diff --git a/sw/tools/parrot/bebop/wifi_tools/scripts/button_switch b/sw/tools/parrot/bebop/button_switch similarity index 75% rename from sw/tools/parrot/bebop/wifi_tools/scripts/button_switch rename to sw/tools/parrot/bebop/button_switch index 6bd1bd9ca4..2b615fc96e 100644 --- a/sw/tools/parrot/bebop/wifi_tools/scripts/button_switch +++ b/sw/tools/parrot/bebop/button_switch @@ -3,8 +3,8 @@ BLDC_Test_Bench -n -M 1 if [ $(bcmwl ap) -eq 1 ] then - if [ -r /data/ftp/internal_000/scripts/connect2hub ]; then - /data/ftp/internal_000/scripts/connect2hub + if [ -r /data/ftp/internal_000/scripts/pprzstarter ]; then + /data/ftp/internal_000/scripts/pprzstarter else echo "Button activating..." | ulogger -t "ShortPressDebug" -p I /bin/usbnetwork.sh diff --git a/sw/tools/parrot/bebop/wifi_tools/scripts/config_network.script b/sw/tools/parrot/bebop/config_network.script similarity index 100% rename from sw/tools/parrot/bebop/wifi_tools/scripts/config_network.script rename to sw/tools/parrot/bebop/config_network.script diff --git a/sw/tools/parrot/bebop/pprz.conf b/sw/tools/parrot/bebop/pprz.conf new file mode 100644 index 0000000000..f4e75782fe --- /dev/null +++ b/sw/tools/parrot/bebop/pprz.conf @@ -0,0 +1,8 @@ +[Default config file for PPRZ init script ] +[Starts Paparazzi with Bebop as Wifi hotspot] +START_PPRZ=1 +START_TELNET=1 +START_ADB=1 +JOIN_WIFI=0 +WIFI_SSID=pprz +WIFI_AMODE=none diff --git a/sw/tools/parrot/bebop/wifi_tools/scripts/connect2hub b/sw/tools/parrot/bebop/pprzstarter similarity index 100% rename from sw/tools/parrot/bebop/wifi_tools/scripts/connect2hub rename to sw/tools/parrot/bebop/pprzstarter diff --git a/sw/tools/parrot/bebop/wifi_tools/README.md b/sw/tools/parrot/bebop/wifi_tools/README.md deleted file mode 100644 index 3adcf2265e..0000000000 --- a/sw/tools/parrot/bebop/wifi_tools/README.md +++ /dev/null @@ -1,21 +0,0 @@ -# Description -These scripts can be used to connect Bebop 2 drones to a Wi-Fi router, so that (for instance) they may be used in a swarm via a central hub. - -The drone will then function as follows: - Upon starting up, it will search for the router. If the router is found, it will connect to it. - If the router is not found within a specific time, the drone will become the access point, as "normal". - The "4 button press" will also be removed, so this will not have to be done before loading Paparazzi on the drone. - -# How to set it up -To connect the Bebop 2 to a router: -1. Open pprz_swarmhub.conf -2. Write the name of the router after WIFI_SSID -3. Start up the Bebop2 and connect to it normally with your computer's WiFi -4. Start up the router -5. Run connect2ssid.sh -6. The Bebop2 should now turn off and connect to the router. To check that this happened, you can connect to the router and try to ping to it/see all connections. -7. Add to the airframe file of the bebop, in the ap target, the following lines: -~~~~ - - -~~~~ diff --git a/sw/tools/parrot/bebop/wifi_tools/connect2ssid.sh b/sw/tools/parrot/bebop/wifi_tools/connect2ssid.sh deleted file mode 100755 index ba347b3175..0000000000 --- a/sw/tools/parrot/bebop/wifi_tools/connect2ssid.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash - -if [ -z "$1" ] -then -IP="192.168.42.1" -echo "No drone ID specified, using ($IP)" -else -IP="$1" -echo "Drone ID specified, using ($IP)" -fi - -wput -nc -u ./pprz_swarmhub.conf ftp://$IP/internal_000/scripts/pprz.conf -wput -nc -u ./scripts/config_network.script ftp://$IP/internal_000/scripts/config_network.script -wput -nc -u ./scripts/button_switch ftp://$IP/internal_000/scripts/button_switch -wput -nc -u ./scripts/connect2hub ftp://$IP/internal_000/scripts/connect2hub -{ echo "mount -o remount,rw /"; echo "sed -i 's|^exit 0|/data/ftp/internal_000/scripts/connect2hub \& exit 0|' /etc/init.d/rcS"; echo "chmod a+x /etc/init.d/rcS"; echo "chmod a+x /data/ftp/internal_000/scripts/connect2hub"; echo "chmod a+x /data/ftp/internal_000/scripts/button_switch"; echo "chmod a+x /data/ftp/internal_000/scripts/config_network.script"; echo "dos2unix /data/ftp/internal_000/scripts/button_switch"; echo "dos2unix /data/ftp/internal_000/scripts/connect2hub"; echo "dos2unix /data/ftp/internal_000/scripts/pprz.conf"; echo "echo '#!/bin/sh' > /bin/onoffbutton/shortpress_3.sh"; echo "echo '' >> /bin/onoffbutton/shortpress_3.sh"; echo "echo '/data/ftp/internal_000/scripts/button_switch' >> /bin/onoffbutton/shortpress_3.sh"; echo "/sbin/reboot"; sleep 10; } | telnet $IP diff --git a/sw/tools/parrot/bebop/wifi_tools/pprz_swarmhub.conf b/sw/tools/parrot/bebop/wifi_tools/pprz_swarmhub.conf deleted file mode 100644 index 3663ec0bac..0000000000 --- a/sw/tools/parrot/bebop/wifi_tools/pprz_swarmhub.conf +++ /dev/null @@ -1,7 +0,0 @@ -# Config file for PPRZ init script -START_PPRZ=1 -START_TELNET=1 -START_ADB=1 -JOIN_WIFI=1 -WIFI_SSID=linksys388 -WIFI_AMODE=none \ No newline at end of file diff --git a/sw/tools/parrot/bebop/wifi_tools/recoverDrone.sh b/sw/tools/parrot/bebop/wifi_tools/recoverDrone.sh deleted file mode 100755 index 4b227e4d79..0000000000 --- a/sw/tools/parrot/bebop/wifi_tools/recoverDrone.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash - -if [ -z "$1" ] -then -IP="192.168.42.1" -echo "No drone ID specified, using ($IP)" -else -IP="$1" -echo "Drone ID specified, using ($IP)" -fi - -{ echo "mount -o remount,rw /"; echo "sed -i 's|^/data/ftp/internal_000/scripts/connect2hub \& exit 0|exit 0|' /etc/init.d/rcS"; echo "chmod a+x /etc/init.d/rcS"; echo "/sbin/reboot"; sleep 10; } | telnet $IP diff --git a/sw/tools/parrot/bebop/wifi_tools/remove4press.sh b/sw/tools/parrot/bebop/wifi_tools/remove4press.sh deleted file mode 100755 index 6e4afe8134..0000000000 --- a/sw/tools/parrot/bebop/wifi_tools/remove4press.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash - -if [ -z "$1" ] -then -IP="192.168.42.1" -echo "No drone ID specified, using ($IP)" -else -IP="$1" -echo "Drone ID specified, using ($IP)" -fi - -wput -u ./pprz_swarmhub.conf ftp://$IP/internal_000/scripts/pprz.conf -wput -u ./scripts/config_network.script ftp://$IP/internal_000/scripts/config_network.script -wput -u ./scripts/connect2hub ftp://$IP/internal_000/scripts/connect2hub -{ echo "mount -o remount,rw /"; echo "sed -i 's|^exit 0|/data/ftp/internal_000/scripts/connect2hub \& exit 0|' /etc/init.d/rcS"; echo "chmod a+x /etc/init.d/rcS"; echo "chmod a+x /data/ftp/internal_000/scripts/connect2hub"; echo "chmod a+x /data/ftp/internal_000/scripts/config_network.script"; echo "dos2unix /data/ftp/internal_000/scripts/pprz.conf"; echo "/sbin/reboot"; sleep 10; } | telnet $IP diff --git a/sw/tools/parrot/parrot_utils.py b/sw/tools/parrot/parrot_utils.py index e7522f43c5..14252ff1c8 100644 --- a/sw/tools/parrot/parrot_utils.py +++ b/sw/tools/parrot/parrot_utils.py @@ -122,9 +122,9 @@ class ParrotUtils: self.ftp.close() # Execute a command - def execute_command(self, command): + def execute_command(self, command, timeout=5): self.tn.write(bytes(command + '\n', 'utf-8')) - s = self.tn.read_until(bytes(self.prompt, 'utf-8')) + s = self.tn.read_until(bytes(self.prompt, 'utf-8'), timeout) if s.endswith(b'[JS] $ '): s = s[len(command) + 2:-8] elif s.endswith(b'[RS.edu] $ '): @@ -229,7 +229,7 @@ class ParrotUtils: # Reboot the drone def reboot(self): - self.execute_command('reboot') + self.execute_command('reboot', timeout=1) print('The ' + self.uav_name + ' is now rebooting') # Kill a running program @@ -254,12 +254,13 @@ class ParrotUtils: print('Removed directory "' + name + '"') # Upload a new file - def upload_file(self, name, folder=""): + def upload_file(self, name, folder="", kill_prog=True): f = self.split_into_path_and_file(name) - # First kill the running program - self.kill_program(f[1]) - sleep(1) + if kill_prog: + # First kill the running program + self.kill_program(f[1]) + sleep(1) # Make the upload directory and upload the file self.create_directory(self.upload_path + folder)