Coverage for farmbot_sidecar_starter_pack/functions/movements.py: 100%
68 statements
« prev ^ index » next coverage.py v7.4.4, created at 2024-08-31 13:41 -0700
« prev ^ index » next coverage.py v7.4.4, created at 2024-08-31 13:41 -0700
1"""
2MovementControls class.
3"""
5# └── functions/movements.py
6# ├── [BROKER] get_xyz()
7# ├── [BROKER] move()
8# ├── [BROKER] set_home()
9# ├── [BROKER] find_home()
10# ├── [BROKER] find_axis_length()
11# └── [BROKER] check_position()
13from .broker import BrokerConnect
14from .information import Information
16AXES = ["x", "y", "z", "all"]
18def validate_axis(axis):
19 """Validate axis."""
20 if axis not in AXES:
21 raise ValueError(f"Invalid axis: {axis} not in {AXES}")
23class MovementControls():
24 """MovementControls class."""
25 def __init__(self, state):
26 self.broker = BrokerConnect(state)
27 self.info = Information(state)
28 self.state = state
30 def move(self, x, y, z):
31 """Moves to the specified (x, y, z) coordinate."""
32 self.state.print_status(description=f"Moving to ({x}, {y}, {z}).")
34 def axis_overwrite(axis, value):
35 return {
36 "kind": "axis_overwrite",
37 "args": {
38 "axis": axis,
39 "axis_operand": {
40 "kind": "numeric",
41 "args": {
42 "number": value
43 }
44 }
45 }
46 }
48 move_message = {
49 "kind": "move",
50 "args": {},
51 "body": [
52 axis_overwrite("x", x),
53 axis_overwrite("y", y),
54 axis_overwrite("z", z)
55 ]
56 }
58 self.broker.publish(move_message)
60 def set_home(self, axis="all"):
61 """Sets the current position as the home position for a specific axis."""
62 self.state.print_status(description="Setting home position")
64 validate_axis(axis)
66 set_home_message = {
67 "kind": "zero",
68 "args": {
69 "axis": axis
70 }
71 }
72 self.broker.publish(set_home_message)
74 def find_home(self, axis="all", speed=100):
75 """Moves the device to the home position for a specified axis."""
76 self.state.print_status(description="Finding home position")
78 validate_axis(axis)
80 if speed > 100 or speed < 1:
81 error = "ERROR: Speed constrained to 1-100."
82 self.state.print_status(description=error, update_only=True)
83 self.state.error = error
84 return
86 message = {
87 "kind": "find_home",
88 "args": {
89 "axis": axis,
90 "speed": speed
91 }
92 }
93 self.broker.publish(message)
95 def find_axis_length(self, axis="all"):
96 """Finds the length of a specified axis."""
97 self.state.print_status(description="Finding axis length")
99 validate_axis(axis)
101 find_axis_length_message = {
102 "kind": "calibrate",
103 "args": {
104 "axis": axis
105 }
106 }
108 self.broker.publish(find_axis_length_message)
110 def get_xyz(self):
111 """Returns the current (x, y, z) coordinates of the FarmBot."""
112 self.state.print_status(description="Getting current coordinates")
114 tree_data = self.info.read_status()
115 if tree_data is None:
116 error = "ERROR: No location data available."
117 self.state.print_status(description=error, update_only=True)
118 self.state.error = error
119 return None
120 position = tree_data["location_data"]["position"]
122 x_val = position["x"]
123 y_val = position["y"]
124 z_val = position["z"]
126 self.state.print_status(description=f"Current position: {position}.", update_only=True)
127 return position
129 def check_position(self, user_x, user_y, user_z, tolerance):
130 """Verifies position of the FarmBot within specified tolerance range."""
132 user_values = {'x': user_x, 'y': user_y, 'z': user_z}
133 self.state.print_status(description=f"Checking if position is {user_values} with tolerance: {tolerance}.")
135 actual_vals = self.get_xyz()
137 if actual_vals is None:
138 return False
140 x_val = actual_vals["x"]
141 y_val = actual_vals["y"]
142 z_val = actual_vals["z"]
144 for axis in ['x', 'y', 'z']:
145 user_value = user_values[axis]
146 actual_value = actual_vals[axis]
147 if not actual_value - tolerance <= user_value <= actual_value + tolerance:
148 self.state.print_status(
149 description=f"Farmbot is NOT at position.\n Current position: {actual_vals}.",
150 update_only=True)
151 return False
153 self.state.print_status(
154 description=f"Farmbot is at position: {actual_vals}.",
155 update_only=True)
156 return True