2024-01-17 16:46:20 -06:00

206 lines
5.0 KiB
Python
Executable File

#!/usr/bin/env python3
import get_specs
import traceback
import logging
import yaml
from multiprocessing import Process, Manager, Pool, TimeoutError, active_children, log_to_stderr
from multiprocessing.pool import Pool
import multiprocessing
from time import sleep
from util import fprint
from util import run_cmd
import sys
import ur5_control
import os
import signal
config = None
keeprunning = True
arm_ready = False
led_ready = False
camera_ready = False
sensor_ready = False
vm_ready = False
killme = None
#pool = None
def arm_start_callback(res):
global arm_ready
arm_ready = True
def led_start_callback(res):
global led_ready
led_ready = True
def camera_start_callback(res):
global camera_ready
camera_ready = True
def sensor_start_callback(res):
global sensor_ready
sensor_ready = True
def vm_start_callback(res):
global vm_ready
vm_ready = True
def wait_for(val, name):
if val is False:
fprint("waiting for " + name + " to complete...")
while val is False:
sleep(0.1)
def setup_server(pool):
# linux server setup
global config
global counter
global sensor_ready
global camera_ready
global led_ready
global arm_ready
fprint("Starting Jukebox control system...")
pool.apply_async(ur5_control.init, (config["arm"]["ip"],), callback=arm_start_callback)
#pool.apply_async(led_control.init, callback=led_start_callback)
#pool.apply_async(camera_control.init, callback=camera_start_callback)
#pool.apply_async(sensor_control.init, callback=sensor_start_callback)
wait_for(led_ready, "LED controller initialization")
wait_for(sensor_ready, "Sensor Initialization")
wait_for(camera_ready, "Camera initilization")
wait_for(arm_ready, "UR5 initilization")
return True
def mainloop_server(pool):
global config
global counter
global killme
if killme.value > 0:
killall()
counter = counter + 1
def setup_client(pool, config):
# Windows client setup
# Open loading wepage
def run_app():
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def index():
return render_template('index.html')
app.run(debug=True, use_reloader=False)
p = Process(target=run_app)
p.start()
# start Linux server VM
if config["core"]["server"] == "Hyper-V":
run_cmd("Start-VM -Name Jukebox*") # any and all VMs starting with "Jukebox"
# Wait for VM to start and be reachable over the network
#pool.apply_async(vm_control.init, callback=vm_start_callback)
wait_for(vm_ready, "VM Startup")
p.terminate()
return True
def mainloop_client(pool):
sleep(0.1)
"""class Logger(object):
def __init__(self, filename="output.log"):
self.log = open(filename, "a")
self.terminal = sys.stdout
def write(self, message):
self.log.write(message)
#close(filename)
#self.log = open(filename, "a")
try:
self.terminal.write(message)
except:
sleep(0)
def flush(self):
print("",end="")"""
def killall():
procs = active_children()
for proc in procs:
proc.kill()
fprint("All child processes killed")
os.kill(os.getpid(), 9) # dirty kill of self
def killall_signal(a, b):
killall()
def error(msg, *args):
return multiprocessing.get_logger().error(msg, *args)
class LogExceptions(object):
def __init__(self, callable):
self.__callable = callable
def __call__(self, *args, **kwargs):
try:
result = self.__callable(*args, **kwargs)
except Exception as e:
# Here we add some debugging help. If multiprocessing's
# debugging is on, it will arrange to log the traceback
error(traceback.format_exc())
# Re-raise the original exception so the Pool worker can
# clean up
raise
# It was fine, give a normal answer
return result
class LoggingPool(Pool):
def apply_async(self, func, args=(), kwds={}, callback=None):
return Pool.apply_async(self, LogExceptions(func), args, kwds, callback)
if __name__ == "__main__":
#sys.stdout = Logger(filename="output.log")
#sys.stderr = Logger(filename="output.log")
log_to_stderr(logging.DEBUG)
with open('config.yml', 'r') as fileread:
#global config
config = yaml.safe_load(fileread)
with Manager() as manager:
pool = LoggingPool(processes=10)
counter = 0
killme = manager.Value('d', 0)
signal.signal(signal.SIGINT, killall_signal)
if config["core"]["mode"] == "winclient":
if setup_client(pool, config):
while(keeprunning):
mainloop_client(pool)
elif config["core"]["mode"] == "linuxserver":
if setup_server(pool):
while(keeprunning):
mainloop_server(pool)