Change if and read_pin to function the same as v7

this prevents the possibility of reading a sensor and it changing
by the time an if statement is executed
pull/974/head
Connor Rigby 2019-09-13 15:21:54 -07:00
parent b42992c3c8
commit 8a816ba1f4
No known key found for this signature in database
GPG Key ID: 29A88B24B70456E0
7 changed files with 124 additions and 40 deletions

View File

@ -267,23 +267,26 @@ defmodule FarmbotCeleryScript.Compiler do
lhs = lhs =
case lhs_ast do case lhs_ast do
"x" -> "x" ->
quote [location: :keep], do: FarmbotCeleryScript.SysCalls.get_current_x() quote [location: :keep],
do: FarmbotCeleryScript.SysCalls.get_cached_x()
"y" -> "y" ->
quote [location: :keep], do: FarmbotCeleryScript.SysCalls.get_current_y() quote [location: :keep],
do: FarmbotCeleryScript.SysCalls.get_cached_y()
"z" -> "z" ->
quote [location: :keep], do: FarmbotCeleryScript.SysCalls.get_current_z() quote [location: :keep],
do: FarmbotCeleryScript.SysCalls.get_cached_z()
"pin" <> pin -> "pin" <> pin ->
quote [location: :keep], quote [location: :keep],
do: FarmbotCeleryScript.SysCalls.read_pin(unquote(String.to_integer(pin)), nil) do: FarmbotCeleryScript.SysCalls.read_cached_pin(unquote(String.to_integer(pin)))
# Named pin has two intents here # Named pin has two intents here
# in this case we want to read the named pin. # in this case we want to read the named pin.
%AST{kind: :named_pin} = ast -> %AST{kind: :named_pin} = ast ->
quote [location: :keep], quote [location: :keep],
do: FarmbotCeleryScript.SysCalls.read_pin(unquote(compile_ast(ast)), nil) do: FarmbotCeleryScript.SysCalls.read_cached_pin(unquote(compile_ast(ast)))
%AST{} = ast -> %AST{} = ast ->
compile_ast(ast) compile_ast(ast)

View File

@ -38,6 +38,11 @@ defmodule FarmbotCeleryScript.SysCalls do
@callback get_current_x() :: number() | error() @callback get_current_x() :: number() | error()
@callback get_current_y() :: number() | error() @callback get_current_y() :: number() | error()
@callback get_current_z() :: number() | error() @callback get_current_z() :: number() | error()
@callback get_cached_x() :: number() | error()
@callback get_cached_y() :: number() | error()
@callback get_cached_z() :: number() | error()
@callback get_sequence(resource_id) :: FarmbotCeleryScript.AST.t() | error() @callback get_sequence(resource_id) :: FarmbotCeleryScript.AST.t() | error()
@callback get_toolslot_for_tool(resource_id) :: @callback get_toolslot_for_tool(resource_id) ::
%{x: number(), y: number(), z: number()} | error() %{x: number(), y: number(), z: number()} | error()
@ -51,6 +56,7 @@ defmodule FarmbotCeleryScript.SysCalls do
@callback point(point_type :: String.t(), resource_id) :: number() | error() @callback point(point_type :: String.t(), resource_id) :: number() | error()
@callback power_off() :: ok_or_error @callback power_off() :: ok_or_error
@callback read_pin(pin_num :: number(), pin_mode :: number()) :: number | error() @callback read_pin(pin_num :: number(), pin_mode :: number()) :: number | error()
@callback read_cached_pin(pin_num :: number()) :: number | error()
@callback toggle_pin(pin_num :: number()) :: ok_or_error @callback toggle_pin(pin_num :: number()) :: ok_or_error
@callback read_status() :: ok_or_error @callback read_status() :: ok_or_error
@callback reboot() :: ok_or_error @callback reboot() :: ok_or_error
@ -184,6 +190,18 @@ defmodule FarmbotCeleryScript.SysCalls do
number_or_error(sys_calls, :get_current_z, []) number_or_error(sys_calls, :get_current_z, [])
end end
def get_cached_x(sys_calls \\ @sys_calls) do
number_or_nil_or_error(sys_calls, :get_cached_x, [])
end
def get_cached_y(sys_calls \\ @sys_calls) do
number_or_nil_or_error(sys_calls, :get_cached_y, [])
end
def get_cached_z(sys_calls \\ @sys_calls) do
number_or_nil_or_error(sys_calls, :get_cached_z, [])
end
def get_sequence(sys_calls \\ @sys_calls, sequence_id) do def get_sequence(sys_calls \\ @sys_calls, sequence_id) do
case sys_calls.get_sequence(sequence_id) do case sys_calls.get_sequence(sequence_id) do
%AST{} = ast -> ast %AST{} = ast -> ast
@ -236,6 +254,10 @@ defmodule FarmbotCeleryScript.SysCalls do
number_or_error(sys_calls, :read_pin, [pin_num, pin_mode]) number_or_error(sys_calls, :read_pin, [pin_num, pin_mode])
end end
def read_cached_pin(sys_calls \\ @sys_calls, pin_num) do
number_or_nil_or_error(sys_calls, :read_cached_pin, [pin_num])
end
def toggle_pin(sys_calls \\ @sys_calls, pun_num) do def toggle_pin(sys_calls \\ @sys_calls, pun_num) do
ok_or_error(sys_calls, :toggle_pin, [pun_num]) ok_or_error(sys_calls, :toggle_pin, [pun_num])
end end
@ -298,6 +320,14 @@ defmodule FarmbotCeleryScript.SysCalls do
end end
end end
defp number_or_nil_or_error(sys_calls, fun, args) do
case apply(sys_calls, fun, args) do
result when is_number(result) -> result
nil -> nil
error -> or_error(sys_calls, fun, args, error)
end
end
defp coord_or_error(sys_calls, fun, args) do defp coord_or_error(sys_calls, fun, args) do
case apply(sys_calls, fun, args) do case apply(sys_calls, fun, args) do
%{x: x, y: y, z: z} = coord when is_number(x) when is_number(y) when is_number(z) -> coord %{x: x, y: y, z: z} = coord when is_number(x) when is_number(y) when is_number(z) -> coord

View File

@ -64,6 +64,15 @@ defmodule FarmbotCeleryScript.SysCalls.Stubs do
@impl true @impl true
def get_current_z(), do: error(:get_current_z, []) def get_current_z(), do: error(:get_current_z, [])
@impl true
def get_cached_x(), do: error(:get_cached_x, [])
@impl true
def get_cached_y(), do: error(:get_cached_y, [])
@impl true
def get_cached_z(), do: error(:get_cached_z, [])
@impl true @impl true
def get_sequence(resource_id), do: error(:get_sequence, [resource_id]) def get_sequence(resource_id), do: error(:get_sequence, [resource_id])
@ -94,6 +103,9 @@ defmodule FarmbotCeleryScript.SysCalls.Stubs do
@impl true @impl true
def read_pin(pin_num, pin_mode), do: error(:read_pin, [pin_num, pin_mode]) def read_pin(pin_num, pin_mode), do: error(:read_pin, [pin_num, pin_mode])
@impl true
def read_cached_pin(pin_num), do: error(:read_cached_pin, [pin_num])
@impl true @impl true
def toggle_pin(pin_num), do: error(:toggle_pin, [pin_num]) def toggle_pin(pin_num), do: error(:toggle_pin, [pin_num])

View File

@ -66,6 +66,9 @@ defmodule FarmbotOS.SysCalls do
@impl true @impl true
defdelegate read_pin(number, mode), to: PinControl defdelegate read_pin(number, mode), to: PinControl
@impl true
defdelegate read_cached_pin(number), to: PinControl
@impl true @impl true
defdelegate write_pin(number, mode, value), to: PinControl defdelegate write_pin(number, mode, value), to: PinControl
@ -171,6 +174,21 @@ defmodule FarmbotOS.SysCalls do
get_position(:z) get_position(:z)
end end
@impl true
def get_cached_x do
get_cached_position(:x)
end
@impl true
def get_cached_y do
get_cached_position(:y)
end
@impl true
def get_cached_z do
get_cached_position(:z)
end
@impl true @impl true
def zero(axis) do def zero(axis) do
axis = assert_axis!(axis) axis = assert_axis!(axis)
@ -211,6 +229,16 @@ defmodule FarmbotOS.SysCalls do
end end
end end
def get_cached_position() do
%{x: x, y: y, z: z} = FarmbotCore.BotState.fetch().location_data.position
[x: x, y: y, z: z]
end
def get_cached_position(axis) do
axis = assert_axis!(axis)
Keyword.fetch!(get_cached_position(), axis)
end
@impl true @impl true
def move_absolute(x, y, z, speed) do def move_absolute(x, y, z, speed) do
do_move_absolute(x, y, z, speed, max_retries()) do_move_absolute(x, y, z, speed, max_retries())

View File

@ -9,6 +9,14 @@ defmodule FarmbotOS.SysCalls.PinControl do
require FarmbotCore.Logger require FarmbotCore.Logger
def read_cached_pin(%_{pin: number}) do
read_cached_pin(number)
end
def read_cached_pin(pin_number) do
FarmbotCore.BotState.fetch().pins()[pin_number][:value]
end
def toggle_pin(pin_number) when is_number(pin_number) do def toggle_pin(pin_number) when is_number(pin_number) do
peripheral = Asset.get_peripheral_by_pin(pin_number) peripheral = Asset.get_peripheral_by_pin(pin_number)
@ -198,19 +206,16 @@ defmodule FarmbotOS.SysCalls.PinControl do
end end
# Peripheral digital # Peripheral digital
def write_pin(%Peripheral{pin: pin, label: label}, 0, 1) do def write_pin(%Peripheral{pin: pin, label: _label}, 0, 1) do
FarmbotCore.Logger.info(2, "Turning the #{label} ON (digital)")
do_write_pin(pin, 0, 1) do_write_pin(pin, 0, 1)
end end
def write_pin(%Peripheral{pin: pin, label: label}, 0, 0) do def write_pin(%Peripheral{pin: pin, label: _label}, 0, 0) do
FarmbotCore.Logger.info(2, "Turning the #{label} OFF (digital)")
do_write_pin(pin, 0, 0) do_write_pin(pin, 0, 0)
end end
# Peripheral analog # Peripheral analog
def write_pin(%Peripheral{pin: pin, label: label}, 1, value) do def write_pin(%Peripheral{pin: pin, label: _label}, 1, _value) do
FarmbotCore.Logger.info(2, "Setting the #{label} to #{value} (analog)")
do_write_pin(pin, 0, 0) do_write_pin(pin, 0, 0)
end end
@ -248,17 +253,14 @@ defmodule FarmbotOS.SysCalls.PinControl do
# Generic pin digital # Generic pin digital
def write_pin(pin, 0, 1) do def write_pin(pin, 0, 1) do
FarmbotCore.Logger.info(2, "Turning pin #{pin} ON (digital)")
do_write_pin(pin, 0, 1) do_write_pin(pin, 0, 1)
end end
def write_pin(pin, 0, 0) do def write_pin(pin, 0, 0) do
FarmbotCore.Logger.info(2, "Turning pin #{pin} OFF (digital)")
do_write_pin(pin, 0, 0) do_write_pin(pin, 0, 0)
end end
def write_pin(pin, 1, value) do def write_pin(pin, 1, value) do
FarmbotCore.Logger.info(2, "Setting pin #{pin} to #{value} (analog)")
do_write_pin(pin, 1, value) do_write_pin(pin, 1, value)
end end

View File

@ -22,7 +22,7 @@ defmodule FarmbotOS.SysCalls.SendMessage do
def render(templ) do def render(templ) do
with {:ok, pos} <- pos(), with {:ok, pos} <- pos(),
{:ok, pins} <- pins(Enum.to_list(0..69)), {:ok, pins} <- pins(),
env <- Keyword.merge(pos, pins) do env <- Keyword.merge(pos, pins) do
env = Map.new(env, fn {k, v} -> {to_string(k), to_string(v)} end) env = Map.new(env, fn {k, v} -> {to_string(k), to_string(v)} end)
@ -44,33 +44,22 @@ defmodule FarmbotOS.SysCalls.SendMessage do
end end
def pos do def pos do
case FarmbotFirmware.request({:position_read, []}) do [x: x, y: y, z: z] = FarmbotOS.SysCalls.get_cached_position()
{:ok, {_, {:report_position, [x: x, y: y, z: z]}}} ->
{:ok,
[
x: FarmbotCeleryScript.FormatUtil.format_float(x),
y: FarmbotCeleryScript.FormatUtil.format_float(y),
z: FarmbotCeleryScript.FormatUtil.format_float(z)
]}
{:error, reason} -> {:ok,
{:error, inspect(reason)} [
end x: FarmbotCeleryScript.FormatUtil.format_float(x),
y: FarmbotCeleryScript.FormatUtil.format_float(y),
z: FarmbotCeleryScript.FormatUtil.format_float(z)
]}
end end
def pins(nums, acc \\ []) def pins() do
{:ok,
def pins([p | rest], acc) do FarmbotCore.BotState.fetch().pins
case FarmbotFirmware.request({:pin_read, [p: p]}) do |> Map.new()
{:ok, {_, {:report_pin_value, [p: ^p, v: v]}}} -> |> Enum.map(fn {p, %{value: v}} ->
v = FarmbotCeleryScript.FormatUtil.format_float(v) {:"pin#{p}", FarmbotCeleryScript.FormatUtil.format_float(v)}
acc = Keyword.put(acc, :"pin#{p}", v) end)}
pins(rest, acc)
er ->
er
end
end end
def pins([], acc), do: {:ok, acc}
end end

View File

@ -106,6 +106,21 @@ defmodule Farmbot.TestSupport.CeleryScript.TestSysCalls do
call({:get_current_z, []}) call({:get_current_z, []})
end end
@impl true
def get_cached_x do
call({:get_cached_x, []})
end
@impl true
def get_cached_y do
call({:get_cached_y, []})
end
@impl true
def get_cached_z do
call({:get_cached_z, []})
end
@impl true @impl true
def write_pin(pin_number, mode, value) do def write_pin(pin_number, mode, value) do
call({:write_pin, [pin_number, mode, value]}) call({:write_pin, [pin_number, mode, value]})
@ -121,6 +136,11 @@ defmodule Farmbot.TestSupport.CeleryScript.TestSysCalls do
call({:read_pin, [number, mode]}) call({:read_pin, [number, mode]})
end end
@impl true
def read_cached_pin(number) do
call({:read_cached_pin, [number]})
end
@impl true @impl true
def toggle_pin(number) do def toggle_pin(number) do
call({:toggle_pin, [number]}) call({:toggle_pin, [number]})