Skip to content

Commit dfcf10e

Browse files
authored
Merge pull request #1443 from FarmBot/staging
Staging => Main (Stable Release v14.6.2)
2 parents ab64755 + a7327b8 commit dfcf10e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+20131
-19225
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
# Changelog
22

3+
# 14.6.2
4+
5+
* Fix bug where Lua scripts would not stop sending GCode during estop
6+
* Genesis and Express firmware updates.
7+
* Improved Lua error legibility.
8+
* Technical preview of load sense API
9+
* Routine dependency upgrades.
10+
311
# 14.6.1
412

513
* Remove need to download farmwares over the network (improves offline experience)

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
14.6.1
1+
14.6.2

lib/core/asset/firmware_config.ex

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ defmodule FarmbotOS.Asset.FirmwareConfig do
4545
field(:movement_calibration_deadzone_x, :float)
4646
field(:movement_calibration_deadzone_y, :float)
4747
field(:movement_calibration_deadzone_z, :float)
48+
field(:movement_calibration_retry_total_x, :float)
49+
field(:movement_calibration_retry_total_y, :float)
50+
field(:movement_calibration_retry_total_z, :float)
4851
field(:movement_calibration_retry_x, :float)
4952
field(:movement_calibration_retry_y, :float)
5053
field(:movement_calibration_retry_z, :float)
@@ -124,6 +127,8 @@ defmodule FarmbotOS.Asset.FirmwareConfig do
124127
field(:pin_guard_5_active_state, :float)
125128
field(:pin_guard_5_pin_nr, :float)
126129
field(:pin_guard_5_time_out, :float)
130+
field(:pin_report_1_pin_nr, :float)
131+
field(:pin_report_2_pin_nr, :float)
127132
timestamps()
128133
end
129134

@@ -212,6 +217,12 @@ defmodule FarmbotOS.Asset.FirmwareConfig do
212217
movement_min_spd_y: firmware_config.movement_min_spd_y,
213218
movement_min_spd_z: firmware_config.movement_min_spd_z,
214219
movement_min_spd_z2: firmware_config.movement_min_spd_z2,
220+
movement_calibration_retry_total_x:
221+
firmware_config.movement_calibration_retry_total_x,
222+
movement_calibration_retry_total_y:
223+
firmware_config.movement_calibration_retry_total_y,
224+
movement_calibration_retry_total_z:
225+
firmware_config.movement_calibration_retry_total_z,
215226
movement_motor_current_x: firmware_config.movement_motor_current_x,
216227
movement_motor_current_y: firmware_config.movement_motor_current_y,
217228
movement_motor_current_z: firmware_config.movement_motor_current_z,
@@ -256,7 +267,9 @@ defmodule FarmbotOS.Asset.FirmwareConfig do
256267
pin_guard_4_time_out: firmware_config.pin_guard_4_time_out,
257268
pin_guard_5_active_state: firmware_config.pin_guard_5_active_state,
258269
pin_guard_5_pin_nr: firmware_config.pin_guard_5_pin_nr,
259-
pin_guard_5_time_out: firmware_config.pin_guard_5_time_out
270+
pin_guard_5_time_out: firmware_config.pin_guard_5_time_out,
271+
pin_report_1_pin_nr: firmware_config.pin_report_1_pin_nr,
272+
pin_report_2_pin_nr: firmware_config.pin_report_2_pin_nr
260273
}
261274
end
262275

@@ -285,6 +298,11 @@ defmodule FarmbotOS.Asset.FirmwareConfig do
285298
:encoder_type_z,
286299
:encoder_use_for_pos_x,
287300
:encoder_use_for_pos_y,
301+
:movement_calibration_retry_total_x,
302+
:movement_calibration_retry_total_y,
303+
:movement_calibration_retry_total_z,
304+
:pin_report_1_pin_nr,
305+
:pin_report_2_pin_nr,
288306
:encoder_use_for_pos_z,
289307
:movement_axis_nr_steps_x,
290308
:movement_axis_nr_steps_y,

lib/firmware/command.ex

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,16 +58,15 @@ defmodule FarmbotOS.Firmware.Command do
5858
# F16 Find length of Z axis (measure length + find 0) *
5959
def find_length(:z), do: schedule(:F16, [])
6060

61-
# # F21(P) Read parameter
62-
def read_param(param), do: schedule(:F21, P: param)
63-
6461
# F82
6562
def report_current_position() do
6663
schedule(:F82, [])
6764
pos = %{x: _, y: _, z: _} = cached_position()
6865
{:ok, pos}
6966
end
7067

68+
def watch_pin(pin_number), do: schedule(:F22, P: 199, V: pin_number)
69+
7170
# F43(P, M) Set the I/O mode M (input=0/output=1) of a pin P in arduino
7271
def set_pin_io_mode(pin, mode) do
7372
write_pm(43, pin, mode)

lib/firmware/config_uploader.ex

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -58,28 +58,16 @@ defmodule FarmbotOS.Firmware.ConfigUploader do
5858
state
5959
end
6060

61-
# Ignore :param_version
62-
defp do_verify_param(_, {0, _}), do: nil
63-
# Ignore :param_test
64-
defp do_verify_param(_, {1, _}), do: nil
65-
# Ignore :param_config_ok
66-
defp do_verify_param(_, {2, _}), do: nil
67-
# Ignore :param_use_eeprom
68-
defp do_verify_param(_, {3, _}), do: nil
69-
70-
defp do_verify_param(nil, _conf) do
71-
end
61+
@ignored_params [0, 1, 2, 3]
62+
63+
defp do_verify_param(_, {p, _}) when p in @ignored_params, do: nil
64+
defp do_verify_param(nil, _conf), do: nil
7265

7366
defp do_verify_param(conf, {p, actual}) do
7467
key = Parameter.translate(p)
7568
expected = Map.fetch!(conf, key)
7669

7770
unless actual == expected do
78-
a = inspect(actual)
79-
e = inspect(expected)
80-
k = inspect(key)
81-
Logger.warn("Expected #{k} to eq #{e}. Got: #{a}")
82-
else
8371
:ok = BotState.set_firmware_config(key, actual)
8472
end
8573
end

lib/firmware/gcode_decoder.ex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ defmodule FarmbotOS.Firmware.GCodeDecoder do
2525
"21" => :param_value_report,
2626
"23" => :report_updated_param_during_calibration,
2727
"41" => :pin_value_report,
28+
"61" => :report_pin_monitor_analog_value,
2829
"71" => :x_axis_timeout,
2930
"72" => :y_axis_timeout,
3031
"73" => :z_axis_timeout,

lib/firmware/inbound_side_effects.ex

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ defmodule FarmbotOS.Firmware.InboundSideEffects do
44
alias FarmbotOS.{
55
Asset,
66
BotState,
7+
Firmware.GCode,
78
Firmware.TxBuffer,
89
Firmware.UARTCoreSupport,
910
FirmwareEstopTimer,
@@ -219,6 +220,22 @@ defmodule FarmbotOS.Firmware.InboundSideEffects do
219220
defp reduce({:y_axis_timeout, _}, s), do: s
220221
defp reduce({:z_axis_timeout, _}, s), do: s
221222

223+
defp reduce(
224+
{:report_pin_monitor_analog_value, %{pin_or_param: p, value1: v}},
225+
s
226+
) do
227+
watcher = s.pin_watcher
228+
229+
if watcher && Process.alive?(watcher) do
230+
send(watcher, {:pin_data, p, v})
231+
s
232+
else
233+
# Turn off pin watching if the watcher dies.
234+
off = GCode.new(:F22, P: 199, V: 0)
235+
TxBuffer.push(%{s | pin_watcher: nil}, nil, off)
236+
end
237+
end
238+
222239
defp reduce(unknown, state) do
223240
msg = "=== Unhandled inbound side effects: #{inspect(unknown)}"
224241
FarmbotOS.Logger.info(3, msg)

lib/firmware/parameter.ex

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,11 @@ defmodule FarmbotOS.Firmware.Parameter do
9898
{171, :movement_calibration_deadzone_x},
9999
{172, :movement_calibration_deadzone_y},
100100
{173, :movement_calibration_deadzone_z},
101+
{175, :movement_calibration_retry_total_x},
102+
{176, :movement_calibration_retry_total_y},
103+
{177, :movement_calibration_retry_total_z},
104+
{198, :pin_report_1_pin_nr},
105+
{199, :pin_report_2_pin_nr},
101106
{201, :pin_guard_1_pin_nr},
102107
{202, :pin_guard_1_time_out},
103108
{203, :pin_guard_1_active_state},

lib/firmware/uart_core.ex

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ defmodule FarmbotOS.Firmware.UARTCore do
3232
fw_type: nil,
3333
rx_count: 0,
3434
rx_buffer: RxBuffer.new(),
35-
tx_buffer: TxBuffer.new()
35+
tx_buffer: TxBuffer.new(),
36+
pin_watcher: nil
3637

3738
# The Firmware has a 120 second default timeout.
3839
# Queuing up 10 messages that take one minute each == 10 minutes.
@@ -51,6 +52,16 @@ defmodule FarmbotOS.Firmware.UARTCore do
5152
@bugfix_timeout 60_000
5253
# ===== END HISTORICAL CODE ==============================
5354

55+
def watch_pin(server \\ __MODULE__, pin_number) do
56+
send(server, {:watch_pin, self()})
57+
FarmbotOS.Firmware.Command.watch_pin(pin_number)
58+
end
59+
60+
def unwatch_pin(server \\ __MODULE__) do
61+
send(server, :unwatch_pin)
62+
FarmbotOS.Firmware.Command.watch_pin(0)
63+
end
64+
5465
# This is a helper method that I use for inspecting GCode
5566
# over SSH. It is not used by production systems except for
5667
# debugging.
@@ -97,6 +108,15 @@ defmodule FarmbotOS.Firmware.UARTCore do
97108
{:ok, state}
98109
end
99110

111+
def handle_info({:watch_pin, watcher}, state) do
112+
if state.pin_watcher, do: raise("Pin observer did not cleanly exit!")
113+
{:noreply, Map.put(state, :pin_watcher, watcher)}
114+
end
115+
116+
def handle_info(:unwatch_pin, state) do
117+
{:noreply, Map.put(state, :pin_watcher, nil)}
118+
end
119+
100120
def handle_info(:reset_state, %State{uart_path: old_path} = state1) do
101121
# Teardown existing connection.
102122
Support.disconnect(state1, "Rebooting firmware")

lib/os/lua.ex

Lines changed: 28 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,15 @@ defmodule FarmbotOS.Lua do
33
Embedded scripting language for "formulas" in the MOVE block,
44
assertion, and general scripting via LUA block.
55
"""
6-
7-
@type t() :: tuple()
8-
@type table() :: [{any, any}]
96
require FarmbotOS.Logger
107
require Logger
118

129
alias FarmbotOS.Lua.{
1310
DataManipulation,
1411
Firmware,
1512
Info,
16-
Wait
13+
Wait,
14+
PinWatcher
1715
}
1816

1917
# this function is used by SysCalls, but isn't a direct requirement.
@@ -48,44 +46,11 @@ defmodule FarmbotOS.Lua do
4846
`extra_vm_args` is a set of extra args to place inside the
4947
Lua sandbox. The extra args are passed to set_table/3
5048
"""
51-
def perform_lua(lua_code, extra_vm_args, comment) do
52-
comment = comment || "sequence"
49+
def perform_lua(lua_code, extra_vm_args, _comment) do
5350
lua_code = add_implicit_return(lua_code)
5451
reducer = fn args, vm -> apply(__MODULE__, :set_table, [vm | args]) end
5552
vm = Enum.reduce(extra_vm_args, init(), reducer)
56-
57-
case raw_eval(vm, lua_code) do
58-
{:ok, value} ->
59-
{:ok, value}
60-
61-
{:error, {:lua_error, error, _lua}} ->
62-
{:error, "lua runtime error evaluating expression: #{inspect(error)}"}
63-
64-
{:error, {:badmatch, {:error, [{line, :luerl_parse, parse_error}], _}}} ->
65-
FarmbotOS.Logger.error(
66-
1,
67-
"""
68-
Failed to parse expression:
69-
`#{comment}.lua:#{line}`
70-
71-
#{IO.iodata_to_binary(parse_error)}
72-
""",
73-
channels: [:toast]
74-
)
75-
76-
{:error,
77-
"failed to parse expression (line:#{line}): #{IO.iodata_to_binary(parse_error)}"}
78-
79-
{:error, error, backtrace} ->
80-
IO.inspect(backtrace, label: "=== LUA ERROR TRACE")
81-
{:error, error}
82-
83-
{:error, error} ->
84-
{:error, error}
85-
86-
error ->
87-
{:error, inspect(error)}
88-
end
53+
FarmbotOS.Lua.Result.new(raw_eval(vm, lua_code))
8954
end
9055

9156
def init do
@@ -102,22 +67,22 @@ defmodule FarmbotOS.Lua do
10267
:luerl.eval(hook, lua)
10368
end
10469

105-
def unquote(:do)(lua, hook) when is_binary(hook) do
106-
:luerl.do(hook, lua)
107-
catch
108-
:error, {:error, reason} ->
109-
{{:error, reason}, lua}
70+
# def unquote(:do)(lua, hook) when is_binary(hook) do
71+
# :luerl.do(hook, lua)
72+
# catch
73+
# :error, {:error, reason} ->
74+
# {{:error, reason}, lua}
11075

111-
error, reason ->
112-
{{:error, {error, reason}}, lua}
113-
end
76+
# error, reason ->
77+
# {{:error, {error, reason}}, lua}
78+
# end
11479

11580
# Wrap a function so that it cannot be called when device
11681
# is locked.
11782
def safe(action, fun) when is_function(fun, 2) do
11883
fn args, lua ->
11984
if FarmbotOS.Firmware.UARTCoreSupport.locked?() do
120-
{[nil, "Can't #{action} when locked."], :luerl.stop(lua)}
85+
{[nil, "Can't #{action} when locked."], disabled_sandbox()}
12186
else
12287
fun.(args, lua)
12388
end
@@ -186,7 +151,22 @@ defmodule FarmbotOS.Lua do
186151
update_fbos_config: &DataManipulation.update_fbos_config/2,
187152
update_firmware_config: &DataManipulation.update_firmware_config/2,
188153
wait: &Wait.wait/2,
154+
watch_pin: &PinWatcher.new/2,
189155
write_pin: safe("write pin", &Firmware.write_pin/2)
190156
}
191157
end
158+
159+
# WHAT IS GOING ON HERE?:
160+
# * We want to allow some Lua to execute when the bot
161+
# is estopped.
162+
# * If the bot is estopped, we DO NOT want it to perform
163+
# unsafe actions like motor movement.
164+
# * If execution reaches this point, you are estopped
165+
# and you get this far, it means you tried to move
166+
# the bot or perform an unsafe action.
167+
# * For safety, we will revert the Lua VM to an empty
168+
# state.
169+
def disabled_sandbox() do
170+
:luerl.set_table([:estop], true, :luerl.init())
171+
end
192172
end

0 commit comments

Comments
 (0)