我目前正在攻读嵌入式硕士学位,我的论文必须研究 Erlang 对机器人编程的有效性。 AFAIK Erlang 的声明性和并发性可以是有效的,所以我为“自适应巡航控制”编写了一个 Erlang 代码,从 C 程序中获取传感器值(因为 Erlang 无法直接读取传感器)然后执行计算并发回控制信号到 C 程序。但代码看起来相当大(行)。 为什么我无法使用声明性或者还有其他问题? 这是我的代码片段。
start() ->
spawn( cr, read_sensor, []),
spawn(cr, take_decision, []),
sleep_infinite().
% this will make it to run infinitely
sleep_infinite() ->
receive
after infinity ->
true
end.
read_sensor() ->
register(read, self()),
Port = open_port({spawn , "./cr_cpgm" }, [{packet, 2}]),
Port ! {self(),{command, [49]}},% for executing read sensor fun in C pgm
read_reply(Port).
read_reply(Port) ->
receive
read_sensor ->
Port ! { self(), { command, [49]}};
{Port, {data, Data}} ->
[Left,Center,Right,Distance] = Data, % stored values of sensors into variables for further computation
io:format("value of Left: ~w and Center: ~w and Right: ~w and Distance: ~w~n",[Left,Center,Right,Distance]),
if Distance =< 100 -> decision ! {1, out}; % Distance shows the value returned by front sharp sensor
((Left > 25) and (Center > 25) and (Right > 25)) -> decision ! {2, out}; % stop robot
Center < 25 -> decision ! {3, out}; % move forward
((Left > 25) and (Center > 25)) -> decision ! {4, out}; % turn right
((Right > 25) and (Center > 25)) -> decision ! {5, out}; % turn left
true -> decision ! {6, out} % no match stop robot
end
end,
read_reply(Port).
take_decision() ->
register(decision, self()),
Port = open_port({spawn , "./cr_cpgm" }, [{packet, 2}]),
decision_reply(Port).
decision_reply(Port) ->
receive
{A, out} ->
Port ! {self(), {command, [50,A]}};
{Port,{data, Data}} ->
if
Data == [102] -> read ! read_sensor %
end
end,
decision_reply(Port).
这段代码看起来更像是 C 代码。
请建议我如何展示 Erlang 在机器人编程中的有效性。欢迎所有建议。
谢谢..
好吧我同意@cthulahoops的观点,这个问题不足以显示Erlang的有效性。有人可以建议一些我可以在 Erlang 中实现的机器人应用程序吗?
首先我想说,这听起来并不是一个很好的展示 Erlang 有效性的项目。
为了让代码更具声明性,首先想到的是将 if 拆分成一个单独的函数,如下所示:
choice(Distance, _Left, _Center, _Right) when Distance =< 100 -> something_you_didnt_say_what;
choice(_Distance, Left, Center, Right) when Left > 25, Center > 25, Right > 25 -> stop;
choice(_Distance, Left, _Center, _Right) when Center < 25 -> forward;
choice(_Distance, Left, Center, _Right) when Center > 25, Left > 25 -> right;
choice(_Distance, _Left, Center, Right) when Center > 25, Right > 25 -> left.
这将如何响应传感器的声明与循环和发送消息等混乱的业务分开。此外,返回原子而不是神秘的整数可以避免将该信息放入注释中。 (遵循注释的哲学告诉你哪里需要澄清代码。)
示例:如果您有多个机器人,它们会以某种方式进行交互,并且每个机器人都有自己的逻辑,由中央 Erlang 服务器控制。
通常,您会创建一个大循环,并在每个循环中放入所有元素的逻辑,如果您使用标准线程,则会使用共享内存和互斥体等丑陋的东西。在 erlang 中,您可以更自然地对其进行编码,并生成浪费最小空间的函数,并让它们通过消息传递进行通信。使用 OTP,您可以创建通用结构来处理常见问题的更烦人的非功能方面,并帮助使其具有监督树的容错能力。您最终会获得更容易阅读的代码以及更高效、更健壮的开发结构。
这就是 erlang 的力量。
如果您需要根据几个变量(右、左等)计算一些决策,您显然不会避免它。问题是如何从使用 erlang 中受益。
在这里,我想到的是实现 OTP 行为之一 - gen_fsm(有限状态机)。因此,逻辑将是(也许/可能?):接收左 -> 仅等待右或中心等等。这将使您的代码非常清晰,并让您有可能根据当前状态产生大量操作,这将导致异步系统完全在您的控制之下。
让我印象深刻的是,Erlang 特别适合机器人群。让群中的每个成员向所有其他成员发送
rpc:abcast
消息,是您必须用程序语言处理的常见 UDP 样板废话的绝佳替代方案。没有绑定到端口,没有为消息指定二进制格式,没有对象序列化等。
只要你能够整理出你所在区域的其他节点的发现,看起来去中心化/分布式的 Erlang swarm 将是一个很棒的项目。