# robi_web.py
# program to control a humanoid robot
#
# the hardware is based on the instructable by Technovation, see:
# https://www.instructables.com/Arduino-Controlled-Robotic-Biped/
#
#
# the software is written in Micropython and requires
# a Raspberri Pi Pico board with MicroPython v1.19 (or later) installed.
#
# by wolf2018, initial version 3-Apr-2022
# rev 19-Jul-2022: integrate with web interface, support for core 1
# rev 3-Feb-2023: finalization of functionality
# rev 14_feb-2023: implement lifetick and gracful shutdown
# rev 25-Feb-2023: cleaning up unused code and comments
# current version:
version_date = "25-Feb-2023"


import cfg
import robi_comm
import _thread
import gc
import wifiConnect
import uasyncio


# assign the pointers to the global objects
status_dict = cfg.status_dict
w_parameter0 = cfg.w_parameter0
w_parameter1 = cfg.w_parameter1    # alternative set of data not used yet


def start_web_if():
    """ function to initialize Robi with the web interface. This allows a user
    to control Robi using the RobiUI"""
    try:
        if cfg.debug > 1:
            input("press ENTER to start webui")
        wifi = wifiConnect.connect()
        if cfg.debug > 1:
            print("got wifi configuration: " + str(wifi))

        cfg.host = wifi[0]

        print(" starting web UI")

        robi_comm.app.run(debug=cfg.debug, host=cfg.host)

    except OSError as e:
        print("exception in start_web_if: "+e)


###################################
# main program starts here


def main():
    try:
        if cfg.debug > 0:
            print("============= starting Robi ==============")
            print("mem: start of main(): " + str(gc.mem_free()))
        gc.collect()
        if cfg.debug > 0:
            print("mem: start of main() after collection: " + str(gc.mem_free()))
        if cfg.debug > 0:
            if cfg.core2:
                print("+++ using both cores +++")
            else:
                print("--- using core 1 only ---")
        # initialize servos
        if cfg.debug > 0:
            print("... init state machines ...")
        cfg.init_sm()
        gc.collect()
        if cfg.debug > 1:
            print("mem: before web if is started: " + str(gc.mem_free()))
        if cfg.debug > 0:
            print("... starting wireless interface ...")
        start_web_if()

    except KeyboardInterrupt:
        print('Got ctrl-c ....... stopping Robi ')
        print("....exiting")
        gc.collect()

    except Exception as e:
        print('mainloop crashed: ', e)

    except SystemExit:
        #
        if cfg.debug > 0:
            print("\n... shutting down robot controller now...")
            print("closing asyncio loop")
        loop = uasyncio.get_event_loop()
        loop.stop()
        loop.close()

    finally:
        print('finally: cleaning up')
        print("de-init state machines for servos")
        cfg.de_init_sm()

        if cfg.core2:
            _thread.exit()

        print("disconnect WLan")
        wifiConnect.disconnect()
        gc.collect()
        print("\n=== shutdown of robot controller complete ===\n")
        # print("free mem: ", gc.mem_free()")

# end of main program
###################################


main()
