4

我目前正在攻读嵌入式硕士学位,对于我的论文,我必须研究 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 在机器人编程中的有效性。欢迎所有建议。

谢谢..

好吧,我同意@cthulahoops 的观点,这个问题不足以证明 Erlang 的有效性。任何人都可以推荐一些我可以在 Erlang 中实现的机器人应用程序吗?

4

4 回答 4

2

好吧,首先我想说这听起来不是一个很好的项目来展示 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.

它将如何响应传感器的声明与循环和发送消息等杂乱事务分开。此外,返回原子而不是神秘的整数避免了将这些信息放入注释中。(遵循注释哲学告诉你需要在哪里澄清代码。)

于 2010-08-21T11:37:16.743 回答
2

示例:如果您有多个机器人,它们将以某种方式进行交互,并且每个机器人都有自己的逻辑,由中央 erlang 服务器控制。

通常,您会创建一个大循环,并在每个循环中放置所有元素的逻辑,如果您使用标准线程,则使用共享内存和互斥锁等丑陋的东西。在 erlang 中,您可以更自然地对其进行编码并生成浪费最少空间的函数并让它们通过消息传递进行通信。使用 OTP,您可以创建通用结构来处理常见问题的更烦人的非功能方面,并通过监督树帮助使其容错。你最终会得到更容易阅读的代码和更高效、更健壮的开发结构。

这就是 erlang 的强大之处。

于 2010-08-22T11:30:50.807 回答
1

如果您需要根据几个变量(右、左等)计算一些决策,您显然不会避免它。问题是如何从使用 erlang 中受益。

在这里,我想到的是实现一种 OTP 行为 - gen_fsm(有限状态机)。因此,逻辑将是(也许/可能?):接收左 -> 仅等待右或中心等等。这将使您的代码非常清晰,并让您有可能根据当前状态生成大量操作,这将导致异步系统完全在您的控制之下。

于 2010-08-21T11:22:29.900 回答
1

令我震惊的是,Erlang 特别适合机器人群。将 swarmrpc:abcast消息中的每个成员发送给所有其他成员是一个很好的替代方案,可以替代您必须用程序语言处理的通常的 UDP 样板废话。没有端口绑定,没有为消息指定二进制格式,没有对象序列化等。

只要你能整理出你所在地区其他节点的发现,看起来去中心化/分布式的 Erlang swarm 将是一个很棒的项目。

于 2011-03-17T01:04:34.507 回答