如何展示 Erlang 对机器人编程的有效性?
我目前正在攻读嵌入式硕士学位,我的论文必须研究 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 代码。
- 我的实现方式是否错误?(尤其是 IF...end)或者问题本身很小(只有 2 个进程)
请建议我如何在机器人编程中展示 Erlang 的有效性。< /strong> 欢迎所有建议。
谢谢..
嗯我同意@cthulahoops的观点,这个问题不足以显示Erlang的有效性。有人可以推荐一些我可以在 Erlang 中实现的机器人应用程序吗?
I am currently pursuing Masters in Embedded and for my thesis I have to study the effectiveness of Erlang for programming Robot. AFAIK Erlang's declarative nature and concurrency can be effective, so I made an Erlang code for "Adaptive cruise control" which takes sensor values from C program(because Erlang can not read sensors directly) then perform computation and send back control signal to C program. But the code looks quite big in size(lines). Why am I not able to use declarative nature or there is some other problem?
Here is my code snippets.
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).
This code looks more like a C code.
- Is my way of implementation wrong?(especially IF...end) or problem itself is small(only 2 processes)
Please suggest me how to show the effectiveness of Erlang in programming robots. All suggestions are welcome.
Thanks..
Well I am agree with @cthulahoops that this problem is not enough to show the effectiveness of Erlang. Can anybody suggest some Robotic application which I can implement in Erlang??
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
嗯,首先我想说,这听起来并不是一个很好的展示 Erlang 有效性的项目。
要使代码更具声明性,首先想到的是将 if 拆分为一个单独的函数,如下所示:
它将如何响应传感器的声明与循环和发送消息等混乱的业务分开。此外,返回原子而不是神秘的整数可以避免将该信息放入注释中。 (遵循注释的哲学告诉你哪里需要澄清代码。)
Well, firstly I'd say that this doesn't sound like a very good project for showing the effectiveness of Erlang.
The first thing that comes to mind to make the code more declarative is to split the if out into a separate function like this:
Which separates the declaration of how to respond to sensors from the messy business of looping and sending messages, etc. Also, returning atoms rather than the cryptic integers avoids having to put that information into comments. (Following the philosophy of comments tell you where you need to clarify the code.)
示例:如果您有多个机器人,它们会以某种方式进行交互,并且每个机器人都有自己的逻辑,由中央 erlang 服务器控制。
通常,您会创建一个大循环,并在每个循环中放入所有元素的逻辑,如果您使用标准线程,则会使用共享内存和互斥体等丑陋的东西。在 erlang 中,您可以更自然地对其进行编码,并生成浪费最小空间的函数,并让它们通过消息传递进行通信。使用 OTP,您可以创建通用结构来处理常见问题的更烦人的非功能方面,并帮助使其具有监督树的容错能力。您最终会获得更容易阅读的代码以及更高效、更健壮的开发结构。
这就是 erlang 的力量。
example: If you had multiple robots which would interact with some way and each had their own logic controlled by a central erlang server.
Normally you'd make a big loop and put the logic of all the elements each cycle through, with ugly stuff like shared memory and mutexes if you utilise standard threads. In erlang you can code it more naturally and spawn functions which waste minimal space and have them communicate via message passing. With OTP you can make generic structures which handle the more annoying non functional aspects to common problems and help make it fault tolerant with supervision trees. You end up with much easier to read code and much more efficient and robust structure to develop in.
That's the power of erlang.
如果您需要根据几个变量(右、左等)计算一些决策,您显然不会避免它。问题是如何从使用 erlang 中受益。
在这里,我想到的是实现 OTP 行为之一 - gen_fsm(有限状态机)。因此,逻辑将是(也许/可能?):接收左 ->仅等待“右”或“中心”等。这将使您的代码非常清晰,并让您有可能根据当前状态产生大量操作,这将导致异步系统完全在您的控制之下。
If you need to calculate some decisions basing on couple variables (Right, Left, etc..) you obviously will not avoid it. The question is how to benefit from using erlang.
Here, what comes to my mind, is implementing one of OTP behaviours - gen_fsm (finite state machine). So, the logic would be (maybe/probably?): Receive Left -> wait only for Right or Center and so on. This would make your code very clear and give you possibility to spawn lots of actions basing on current state, which would result in asynchronous system totally under your control.
让我印象深刻的是,Erlang 特别适合机器人群。让群中的每个成员向所有其他成员发送
rpc:abcast
消息,是您必须用过程语言处理的常见 UDP 样板废话的绝佳替代方案。没有绑定到端口,没有为消息指定二进制格式,没有对象序列化等。只要您可以理清您所在区域中其他节点的发现,似乎去中心化/分布式 Erlang 群就是一个很棒的项目。
It strikes me that Erlang is particularly well-suited for robotic swarms. Having each member of the swarm
rpc:abcast
messages to all the other members is a fantastic alternative to the usual UDP boilerplate crap that you'd have to deal with in a procedural language. There's no binding to ports, no specifying a binary format for your messages, no serializing of objects, etc.As long as you can sort out the discovery of other nodes in your area, it seems like a decentralized/distributed Erlang swarm would be a great project.