Skip to content

Commit 09d690d

Browse files
committed
Added python style check.
1 parent 6551a74 commit 09d690d

File tree

4 files changed

+102
-74
lines changed

4 files changed

+102
-74
lines changed

.github/workflows/python-check.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
name: python style check
2+
on: [push, pull_request]
3+
jobs:
4+
check-python-style:
5+
runs-on: ubuntu-latest
6+
steps:
7+
- uses: actions/checkout@v4
8+
- name: Black Code Formatter
9+
uses: lgeiger/black-action@master
10+
with:
11+
args: ". --check --diff"

README.md

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1-
# Mirte Python API
1+
# MIRTE Python API
2+
This package provides the API for the MIRTE Robot. Please
3+
read the MIRTE documentation.
24

3-
This package provides the API for the Mirte Robot. Please read the Mirte documentation.
5+
# Test code style
6+
To check the Python code style run:
7+
```sh
8+
pip install black
9+
black --check **/**.py
10+
# Fix by using
11+
black **/**.py
12+
```

mirte_robot/linetrace.py

Lines changed: 52 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#!/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
33

44
import sys
55
import os
@@ -14,93 +14,102 @@
1414
from mirte_robot import robot
1515

1616
# 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+
2021

2122
# the stop be stopped when:
2223
# 1) the code finishes
2324
# 2) the user stopped the process
2425
# 3) the websocket connection is closed
2526
def stop_mirte():
26-
global running
27-
if running.value:
27+
global running
28+
if running.value:
2829
process.terminate()
29-
running.value = False
30+
running.value = False
31+
3032

3133
def load_mirte_module(stepper, do_step, running):
3234

3335
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
4345

4446
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
5052

5153
# Send the PID to the web interface and give it some time to call strace on this process
5254
# to see the output of this script
5355
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
5557

5658
sys.settrace(traceit)
5759
# rospy.init_node() for some reason needs to be called from __main__ when importing in the regular way.
5860
# We thereofe need to load teh module from source instead of importing it.
5961
# https://answers.ros.org/question/266612/rospy-init_node-inside-imported-file
6062
test = SourceFileLoader("mirte", "/home/mirte/workdir/mirte.py").load_module()
6163

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:
6365
# https://stackoverflow.com/questions/34506638/how-to-register-atexit-function-in-pythons-multiprocessing-subprocess
6466
# TODO: this assumes we have the robot initlized under variable 'mirte'. As soon as we let them create their own python,
6567
# this might not work anymore.
66-
if hasattr(test, 'mirte'):
67-
test.mirte.stop()
68+
if hasattr(test, "mirte"):
69+
test.mirte.stop()
6870

6971
# Sending the linetrace 0 to the client
7072
server.send_message_to_all("0")
7173
running.value = False
7274
stop_mirte()
7375

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+
7579

7680
def start_mirte():
7781
global process
7882
# process should already have been killed after stop, or disconnect
7983
# but, just in case make sure to stop this
8084
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+
)
8389
process.start()
8490

91+
8592
def client_left(client, server):
8693
stop_mirte()
8794

95+
8896
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+
104113

105114
server = WebsocketServer(host="0.0.0.0", port=8001, loglevel=logging.CRITICAL)
106115
server.set_fn_message_received(message_received)

mirte_robot/robot.py

Lines changed: 28 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151

5252
mirte = {}
5353

54+
5455
class Robot:
5556
"""Robot API
5657
@@ -69,6 +70,7 @@ class Robot:
6970
# function. Therefor the sphynx documentation is not able to process
7071
# this class anymore.
7172
_instance = None
73+
7274
def __new__(cls, *args, **kwargs):
7375
if cls._instance is None:
7476
cls._instance = super(Robot, cls).__new__(cls)
@@ -84,24 +86,24 @@ def __init__(
8486
if getattr(self, "_initialized", False):
8587
return
8688

87-
# Parameters:
88-
# machine_namespace (Optional[str], optional): The Namespace from '/' to the ROS namespace for the specific Mirte. Defaults to "/{HOSTNAME}". (This only has to be changed when running the Robot API from a different machine directly. It is configured correctly for the Web interface)
89-
# hardware_namespace (str, optional): The namespace for the hardware peripherals. Defaults to "io".
90-
91-
self._machine_namespace = "" #(
92-
# machine_namespace
93-
# if machine_namespace and validate_namespace(machine_namespace)
94-
# else "/" + platform.node().replace("-", "_").lower()
95-
# )
96-
self._hardware_namespace = "/io" #(
97-
# hardware_namespace
98-
# if validate_namespace(
99-
# hardware_namespace
100-
# if hardware_namespace.startswith("/")
101-
# else (self._machine_namespace + "/" + hardware_namespace)
102-
# )
103-
# else "io"
104-
# )
89+
# Parameters:
90+
# machine_namespace (Optional[str], optional): The Namespace from '/' to the ROS namespace for the specific Mirte. Defaults to "/{HOSTNAME}". (This only has to be changed when running the Robot API from a different machine directly. It is configured correctly for the Web interface)
91+
# hardware_namespace (str, optional): The namespace for the hardware peripherals. Defaults to "io".
92+
93+
self._machine_namespace = "" # (
94+
# machine_namespace
95+
# if machine_namespace and validate_namespace(machine_namespace)
96+
# else "/" + platform.node().replace("-", "_").lower()
97+
# )
98+
self._hardware_namespace = "/io" # (
99+
# hardware_namespace
100+
# if validate_namespace(
101+
# hardware_namespace
102+
# if hardware_namespace.startswith("/")
103+
# else (self._machine_namespace + "/" + hardware_namespace)
104+
# )
105+
# else "io"
106+
# )
105107

106108
ROS_DISTRO = os.getenv("ROS_DISTRO")
107109

@@ -415,7 +417,6 @@ def finalize(node: rclpy.node.Node, motors: dict[str, rclpy.client.Client]):
415417
self.color_services[sensor]["RGBW"].wait_for_service()
416418
self.color_services[sensor]["HSL"].wait_for_service()
417419

418-
419420
self._node.destroy_client(list_parameters)
420421

421422
self._get_digital_pin_value_service = self._node.create_client(
@@ -444,14 +445,14 @@ def _call_service(
444445
) -> rclpy.client.SrvTypeResponse:
445446

446447
with self._lock:
447-
future_response = client.call_async(request)
448-
while not future_response.done() and not self._stopping:
449-
rclpy.spin_once(self._node, timeout_sec=0.1)
448+
future_response = client.call_async(request)
449+
while not future_response.done() and not self._stopping:
450+
rclpy.spin_once(self._node, timeout_sec=0.1)
450451

451452
if self._stopping:
452-
with self._lock:
453-
self._stopping = False
454-
self._at_exit()
453+
with self._lock:
454+
self._stopping = False
455+
self._at_exit()
455456

456457
return future_response.result()
457458

@@ -863,13 +864,11 @@ def stop(self) -> None:
863864
def getROSNode(self):
864865
return self._node
865866

866-
867867
def _signal_handler(self, sig, frame):
868868
self._stopping = True
869869

870-
if (not self._lock.locked()):
871-
self._at_exit()
872-
870+
if not self._lock.locked():
871+
self._at_exit()
873872

874873
def _at_exit(self) -> None:
875874
self.stop()

0 commit comments

Comments
 (0)