|
1 | 1 | #!/usr/bin/env python |
2 | | -#TODO: for debugging purposes we could *also* listen to keyboard events |
| 2 | +# TODO: for debugging purposes we could *also* listen to keyboard events |
3 | 3 |
|
4 | 4 | import sys |
5 | 5 | import os |
|
14 | 14 | from mirte_robot import robot |
15 | 15 |
|
16 | 16 | # Global shared memory objects (TODO: check if we need shared memory, why is server working?) |
17 | | -stepper = multiprocessing.Value('b', True) |
18 | | -do_step = multiprocessing.Value('b', False) |
19 | | -running = multiprocessing.Value('b', False) |
| 17 | +stepper = multiprocessing.Value("b", True) |
| 18 | +do_step = multiprocessing.Value("b", False) |
| 19 | +running = multiprocessing.Value("b", False) |
| 20 | + |
20 | 21 |
|
21 | 22 | # the stop be stopped when: |
22 | 23 | # 1) the code finishes |
23 | 24 | # 2) the user stopped the process |
24 | 25 | # 3) the websocket connection is closed |
25 | 26 | def stop_mirte(): |
26 | | - global running |
27 | | - if running.value: |
| 27 | + global running |
| 28 | + if running.value: |
28 | 29 | process.terminate() |
29 | | - running.value = False |
| 30 | + running.value = False |
| 31 | + |
30 | 32 |
|
31 | 33 | def load_mirte_module(stepper, do_step, running): |
32 | 34 |
|
33 | 35 | def trace_lines(frame, event, arg): |
34 | | - global do_step |
35 | | - if event != 'line': |
36 | | - return |
37 | | - # Only return line number to websocket when in step mode |
38 | | - if stepper.value: |
39 | | - server.send_message_to_all(str(frame.f_lineno)) |
40 | | - while stepper.value and not do_step.value: |
41 | | - time.sleep(.01) |
42 | | - do_step.value = False |
| 36 | + global do_step |
| 37 | + if event != "line": |
| 38 | + return |
| 39 | + # Only return line number to websocket when in step mode |
| 40 | + if stepper.value: |
| 41 | + server.send_message_to_all(str(frame.f_lineno)) |
| 42 | + while stepper.value and not do_step.value: |
| 43 | + time.sleep(0.01) |
| 44 | + do_step.value = False |
43 | 45 |
|
44 | 46 | def traceit(frame, event, arg): |
45 | | - co = frame.f_code |
46 | | - filename = co.co_filename |
47 | | - if not filename.endswith('mirte.py'): |
48 | | - return |
49 | | - return trace_lines |
| 47 | + co = frame.f_code |
| 48 | + filename = co.co_filename |
| 49 | + if not filename.endswith("mirte.py"): |
| 50 | + return |
| 51 | + return trace_lines |
50 | 52 |
|
51 | 53 | # Send the PID to the web interface and give it some time to call strace on this process |
52 | 54 | # to see the output of this script |
53 | 55 | server.send_message_to_all("pid:" + str(os.getpid())) |
54 | | - time.sleep(0.2) #TODO: let client send signal when strace is started |
| 56 | + time.sleep(0.2) # TODO: let client send signal when strace is started |
55 | 57 |
|
56 | 58 | sys.settrace(traceit) |
57 | 59 | # rospy.init_node() for some reason needs to be called from __main__ when importing in the regular way. |
58 | 60 | # We thereofe need to load teh module from source instead of importing it. |
59 | 61 | # https://answers.ros.org/question/266612/rospy-init_node-inside-imported-file |
60 | 62 | test = SourceFileLoader("mirte", "/home/mirte/workdir/mirte.py").load_module() |
61 | 63 |
|
62 | | - # Stop the motors. The atexit call in robot.py does not work when running from a subprocess: |
| 64 | + # Stop the motors. The atexit call in robot.py does not work when running from a subprocess: |
63 | 65 | # https://stackoverflow.com/questions/34506638/how-to-register-atexit-function-in-pythons-multiprocessing-subprocess |
64 | 66 | # TODO: this assumes we have the robot initlized under variable 'mirte'. As soon as we let them create their own python, |
65 | 67 | # this might not work anymore. |
66 | | - if hasattr(test, 'mirte'): |
67 | | - test.mirte.stop() |
| 68 | + if hasattr(test, "mirte"): |
| 69 | + test.mirte.stop() |
68 | 70 |
|
69 | 71 | # Sending the linetrace 0 to the client |
70 | 72 | server.send_message_to_all("0") |
71 | 73 | running.value = False |
72 | 74 | stop_mirte() |
73 | 75 |
|
74 | | -process = multiprocessing.Process(target = load_mirte_module, args=(stepper, do_step)) |
| 76 | + |
| 77 | +process = multiprocessing.Process(target=load_mirte_module, args=(stepper, do_step)) |
| 78 | + |
75 | 79 |
|
76 | 80 | def start_mirte(): |
77 | 81 | global process |
78 | 82 | # process should already have been killed after stop, or disconnect |
79 | 83 | # but, just in case make sure to stop this |
80 | 84 | if process.is_alive(): |
81 | | - process.terminate() |
82 | | - process = multiprocessing.Process(target = load_mirte_module, args=(stepper, do_step, running)) |
| 85 | + process.terminate() |
| 86 | + process = multiprocessing.Process( |
| 87 | + target=load_mirte_module, args=(stepper, do_step, running) |
| 88 | + ) |
83 | 89 | process.start() |
84 | 90 |
|
| 91 | + |
85 | 92 | def client_left(client, server): |
86 | 93 | stop_mirte() |
87 | 94 |
|
| 95 | + |
88 | 96 | def message_received(client, server, message): |
89 | | - global stepper, do_step, running |
90 | | - |
91 | | - if message == "b": #break (pause) |
92 | | - stepper.value = True |
93 | | - if message == "c": #continue (play) |
94 | | - stepper.value = False |
95 | | - if not running.value: |
96 | | - start_mirte() |
97 | | - running.value = True |
98 | | - if message == "s": #step (step) |
99 | | - do_step.value = True |
100 | | - if message == "e": #exit (stop) |
101 | | - stepper.value = True |
102 | | - do_step.value = False |
103 | | - stop_mirte() |
| 97 | + global stepper, do_step, running |
| 98 | + |
| 99 | + if message == "b": # break (pause) |
| 100 | + stepper.value = True |
| 101 | + if message == "c": # continue (play) |
| 102 | + stepper.value = False |
| 103 | + if not running.value: |
| 104 | + start_mirte() |
| 105 | + running.value = True |
| 106 | + if message == "s": # step (step) |
| 107 | + do_step.value = True |
| 108 | + if message == "e": # exit (stop) |
| 109 | + stepper.value = True |
| 110 | + do_step.value = False |
| 111 | + stop_mirte() |
| 112 | + |
104 | 113 |
|
105 | 114 | server = WebsocketServer(host="0.0.0.0", port=8001, loglevel=logging.CRITICAL) |
106 | 115 | server.set_fn_message_received(message_received) |
|
0 commit comments