38
Boston Elixir Presented by Jean-François Cloutier At the Boston Elixir Meetup March 15, 2016 Building a robot dashboard with Phoenix and Elm

Building a robot dashboard with Phoenix and Elmfiles.meetup.com/18220015/robot_dashboard_phoenix_elm.pdf · Boston Elixir Elm runtime Phoenix signals Elm The main Elm module (RobotDashboard)

  • Upload
    others

  • View
    10

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Building a robot dashboard with Phoenix and Elmfiles.meetup.com/18220015/robot_dashboard_phoenix_elm.pdf · Boston Elixir Elm runtime Phoenix signals Elm The main Elm module (RobotDashboard)

Boston Elixir

Presented by Jean-François Cloutier

At the Boston Elixir Meetup

March 15, 2016

Building a robot dashboard with Phoenix and Elm

Page 2: Building a robot dashboard with Phoenix and Elmfiles.meetup.com/18220015/robot_dashboard_phoenix_elm.pdf · Boston Elixir Elm runtime Phoenix signals Elm The main Elm module (RobotDashboard)

Boston Elixir

See Marv

Infrared sensor (to sense beacon

distance and direction)

Touch sensor(to detect collisions)

Large motors(to move and turn)

Medium motor (turned on when

“eating”)

LEDs(green when moving around, orange when finding food, red

when panicking)

Color sensor (to see the “food”)

Beacon(to simulate the smell of food)

Ultrasonic sensor (to sense

proximity of obstacles)

Speaker(to emote)

Powered by elixir

Page 3: Building a robot dashboard with Phoenix and Elmfiles.meetup.com/18220015/robot_dashboard_phoenix_elm.pdf · Boston Elixir Elm runtime Phoenix signals Elm The main Elm module (RobotDashboard)

Boston Elixir

The blue paper is food.

The beacon above it emits the scent of food.

Marv is curious and likes to roam around.

But when he is hungry, he forages for food instead.

Unless he is scared. Then he panics and runs around like a headless chicken.

What Marv is saying:

“I am hungry”

“Uh oh” (when colliding)

“I am stuck”

“I am scared”

“Nom de nom de nom” (when eating)

See Marv run

Page 4: Building a robot dashboard with Phoenix and Elmfiles.meetup.com/18220015/robot_dashboard_phoenix_elm.pdf · Boston Elixir Elm runtime Phoenix signals Elm The main Elm module (RobotDashboard)

Boston Elixir

https://www.youtube.com/watch?v=NbquttnKuak

See Marv run

Page 5: Building a robot dashboard with Phoenix and Elmfiles.meetup.com/18220015/robot_dashboard_phoenix_elm.pdf · Boston Elixir Elm runtime Phoenix signals Elm The main Elm module (RobotDashboard)

Boston Elixir

Marvin Minsky1927-2016

The society of mind theory views the human mind and any other naturally evolved cognitive systems as a vast society of individually simple processes known as agents. These processes are the fundamental thinking entities from which minds are built, and together produce the many abilities we attribute to minds.

Minds are what brains do

https://en.wikipedia.org/wiki/Society_of_Mind

The great power in viewing a mind as a society of agents, as opposed to the consequence of some basic principle or some simple formal system, is that different agents can be based on different types of processes with different purposes, ways of representing knowledge, and methods for producing results.

Page 6: Building a robot dashboard with Phoenix and Elmfiles.meetup.com/18220015/robot_dashboard_phoenix_elm.pdf · Boston Elixir Elm runtime Phoenix signals Elm The main Elm module (RobotDashboard)

Boston Elixir A (simple) society of agents

Page 7: Building a robot dashboard with Phoenix and Elmfiles.meetup.com/18220015/robot_dashboard_phoenix_elm.pdf · Boston Elixir Elm runtime Phoenix signals Elm The main Elm module (RobotDashboard)

Boston Elixir

Hunger

On track

Food

Started

Foraging behavior

Off track

Feeding

Scentstrength

Scentdirection

Scentdirection

Scentstrength

Food

Colliding(reflex)

Gettingunstuck(reflex)

Stuck Collision

Page 8: Building a robot dashboard with Phoenix and Elmfiles.meetup.com/18220015/robot_dashboard_phoenix_elm.pdf · Boston Elixir Elm runtime Phoenix signals Elm The main Elm module (RobotDashboard)

Boston Elixir

Detector, Internal clock

Detector, Internal clock

PerceptorPerceptor

MotivatorMotivator

BehaviorBehavior

ActuatorActuatorActions cause measures to change

Agents create and react to percepts, motives and intents concurrently

Agents interact indirectly via events dispatched by the CNS, and via the short-term memories they create and retrieve

From these concurrent and indirect interactions, we get a (lively) mess of transient, entangled control loops

All together now

Page 9: Building a robot dashboard with Phoenix and Elmfiles.meetup.com/18220015/robot_dashboard_phoenix_elm.pdf · Boston Elixir Elm runtime Phoenix signals Elm The main Elm module (RobotDashboard)

Boston ElixirMarv's mind map

Page 10: Building a robot dashboard with Phoenix and Elmfiles.meetup.com/18220015/robot_dashboard_phoenix_elm.pdf · Boston Elixir Elm runtime Phoenix signals Elm The main Elm module (RobotDashboard)

Boston Elixir

The urgency of now

A robot must deal with the “here and now”

• It can't afford to react to its situation as it was seconds ago

When the robot is falling behind, it sees increasingly stale percepts, motives or intents

• At some point, they become dangerously out-of-sync with reality

One solution

• Ignore stale percepts, motives and intents● Strong intents take longer to become stale

• And make the robot faint (briefly)● CNS temporarily stops the production of Percepts by Detectors

and by the Internal Clock

● Giving the robot a chance to catch up

Page 11: Building a robot dashboard with Phoenix and Elmfiles.meetup.com/18220015/robot_dashboard_phoenix_elm.pdf · Boston Elixir Elm runtime Phoenix signals Elm The main Elm module (RobotDashboard)

Boston Elixir

A dashboard you said?

Clearly, what goes on in the robot's mind is complex:

• A constant flood of percepts

• Turns motives on and off

• Triggering and halting behaviors

• Each driven by percepts

• And generating intents on state transitions

All of which happens all the time, at the same time

I wanted a dashboard so I could peek into the mind of my robot

Page 12: Building a robot dashboard with Phoenix and Elmfiles.meetup.com/18220015/robot_dashboard_phoenix_elm.pdf · Boston Elixir Elm runtime Phoenix signals Elm The main Elm module (RobotDashboard)

Boston Elixir

The robot dashboard

Pause/resume robot

The robot fainted

Latest value for each type of percepts

Current memory usage

Status of all motives

Green is on, red is off

Strike-through when inhibited

Current state of all behaviors

Green is triggered, red is terminated, yellow is

overwhelmedStrike-through when

inhibitedReflexes are in italics

Latest values of all realized intents

Page 13: Building a robot dashboard with Phoenix and Elmfiles.meetup.com/18220015/robot_dashboard_phoenix_elm.pdf · Boston Elixir Elm runtime Phoenix signals Elm The main Elm module (RobotDashboard)

Boston Elixir

Reading the dashboard

Page 14: Building a robot dashboard with Phoenix and Elmfiles.meetup.com/18220015/robot_dashboard_phoenix_elm.pdf · Boston Elixir Elm runtime Phoenix signals Elm The main Elm module (RobotDashboard)

Boston Elixir

Elmruntime

Under the dashboard

Router

Channel

CNS

ChannelsHandler

events

events

Web sockets (JSON)

View

HTTP

(Rest) Controller

App

UpdateUpdate

ModelModel

ViewView

signals

signals

Elixir/OTP

Phoenix

TaskPorttasks

On the browser On the robot

PortPort

Page 15: Building a robot dashboard with Phoenix and Elmfiles.meetup.com/18220015/robot_dashboard_phoenix_elm.pdf · Boston Elixir Elm runtime Phoenix signals Elm The main Elm module (RobotDashboard)

Boston Elixir

About

Elm is a functional programming language for the browser

• Elm transpiles to Javascript

• Intelligently typed

• Pure functions

Elm is reactive

• Signals in and signals out

• Actions modify the model which modifies the virtual DOM

● The real DOM is then automatically and minimally updated

● No cyclical side-effect cascades or other horrors

Elm is a many-splendored thing

• Very declarative, very fast

• Marvelously informative compiler errors

• If it compiles, you know you won't see runtime errors

From http://staltz.com/unidirectional-user-interface-architectures.html

Page 16: Building a robot dashboard with Phoenix and Elmfiles.meetup.com/18220015/robot_dashboard_phoenix_elm.pdf · Boston Elixir Elm runtime Phoenix signals Elm The main Elm module (RobotDashboard)

Boston Elixir

Elm is small

Few concepts to master:

• Data● Numbers, strings, lists, tuples, records

• Functions● Named or anonymous

• Types● Implied or declared, composable, and never

ambiguous

• Signals● Time-varying values (reactivity!)

• Tasks● Deferred execution of functions

• Modules● To organize, hide and expose functions and types

• Ports● Sanitary access to and from the dirty, side-effect-

ridden outside worldSee http://elm-lang.org/docs/syntax

Page 17: Building a robot dashboard with Phoenix and Elmfiles.meetup.com/18220015/robot_dashboard_phoenix_elm.pdf · Boston Elixir Elm runtime Phoenix signals Elm The main Elm module (RobotDashboard)

Boston Elixir

Elm is functional

All functions all the time

Functions can be curried

Functions can operate on functions

• Mapping, filtering, folding...

From http://package.elm-lang.org/packages/elm-lang/core/3.0.0/List

List

From https://dennisreimann.de/articles/elm-functions.html

Page 18: Building a robot dashboard with Phoenix and Elmfiles.meetup.com/18220015/robot_dashboard_phoenix_elm.pdf · Boston Elixir Elm runtime Phoenix signals Elm The main Elm module (RobotDashboard)

Boston Elixir

Elm runtime (JS)

Elm is

Functions can not cause side-effects “within” Elm

• All side-effects happen “outside”

● In the Elm runtime

• As outgoing Tasks● Delayed executions

of functions

• Or as incoming Signals of Actions

● “To-do's” for updating the model

Elm app

updatefunction

port

immutablemodel

viewfunction

task

Causing side-effects:REST calls,

DB updates etc.

Signals

Strictlyfunctional

Reporting side-effects:

Socket pushes,user interactions...

Page 19: Building a robot dashboard with Phoenix and Elmfiles.meetup.com/18220015/robot_dashboard_phoenix_elm.pdf · Boston Elixir Elm runtime Phoenix signals Elm The main Elm module (RobotDashboard)

Boston Elixir

Elm is reactive

With signals, time becomes a 1st class citizen

• A signal is a stream of values representing a state changing over time (e.g. the position of the mouse)

The application reacts to multiple signals by...

• Constantly re-calculating from merged signals the aggregate state, from time zero to now

• Producing a signal of views on that aggregate state, causing display refreshes

• Creating signals of tasks (think JS

promises) that, when executed, cause external state changes (e.g. DB updates, REST calls etc.)

From http://www.elm-tutorial.org/effects/tasks.html

From http://elm-lang.org/guide/reactivity

Page 20: Building a robot dashboard with Phoenix and Elmfiles.meetup.com/18220015/robot_dashboard_phoenix_elm.pdf · Boston Elixir Elm runtime Phoenix signals Elm The main Elm module (RobotDashboard)

Boston Elixir

Elm is friendly

Excellent tooling

• REPL

• Build tool plugins (brunch, grunt...)

• Code editor support

• Easy install (nmp install ...)

World's best compiler error messages

No runtime errors. Evah!

Page 21: Building a robot dashboard with Phoenix and Elmfiles.meetup.com/18220015/robot_dashboard_phoenix_elm.pdf · Boston Elixir Elm runtime Phoenix signals Elm The main Elm module (RobotDashboard)

Boston Elixir

Integrating Elm and Phoenix

Elm is embedded in the Phoenix application

And integrated in the build (and automatic rebuild) process

• See package.json, brunch-config.js

Phoenix

RobotDashboard.js RobotDashboard.elmapp.js

brunch build

Adapted from http://www.cultivatehq.com/posts/phoenix-elm-2/

Page 22: Building a robot dashboard with Phoenix and Elmfiles.meetup.com/18220015/robot_dashboard_phoenix_elm.pdf · Boston Elixir Elm runtime Phoenix signals Elm The main Elm module (RobotDashboard)

Boston Elixir

Composing the dashboard

AppStatus

Perception

Motivation

Comportment Actuation

Page 23: Building a robot dashboard with Phoenix and Elmfiles.meetup.com/18220015/robot_dashboard_phoenix_elm.pdf · Boston Elixir Elm runtime Phoenix signals Elm The main Elm module (RobotDashboard)

Boston Elixir

Organizing the code

RobotDashboard.elm (the main module)

• StartApp (“main”), input signals and ports

The app module (under App) and component modules (under Status, Perception, Motivation, Comportment and Actuation)

• Model● The model types and functions for instantiation,

initialization

• Update● The update action types and the model update

functions

• View● The HTML generation functions

App structure and framework modeled after Elm-Hedley

Page 24: Building a robot dashboard with Phoenix and Elmfiles.meetup.com/18220015/robot_dashboard_phoenix_elm.pdf · Boston Elixir Elm runtime Phoenix signals Elm The main Elm module (RobotDashboard)

Boston Elixir

Model

Each component defines a model as a record

The payloads of signals from Phoenix are also records Status/Model.elm

Page 25: Building a robot dashboard with Phoenix and Elmfiles.meetup.com/18220015/robot_dashboard_phoenix_elm.pdf · Boston Elixir Elm runtime Phoenix signals Elm The main Elm module (RobotDashboard)

Boston Elixir

Model

The overall model is a record of the components' model records

App/Model.elm

Page 26: Building a robot dashboard with Phoenix and Elmfiles.meetup.com/18220015/robot_dashboard_phoenix_elm.pdf · Boston Elixir Elm runtime Phoenix signals Elm The main Elm module (RobotDashboard)

Boston Elixir

Updating

Actions are defined as union types

The update function responds to actions (carried by

signals) by

• transforming the model

• and potentially creating new actions as effects

Status/Update.elm

Page 27: Building a robot dashboard with Phoenix and Elmfiles.meetup.com/18220015/robot_dashboard_phoenix_elm.pdf · Boston Elixir Elm runtime Phoenix signals Elm The main Elm module (RobotDashboard)

Boston Elixir

Updating

The App's update function

• Receives all actions

• “Peels” and dispatches each action to its target component

App/Update.elm

Page 28: Building a robot dashboard with Phoenix and Elmfiles.meetup.com/18220015/robot_dashboard_phoenix_elm.pdf · Boston Elixir Elm runtime Phoenix signals Elm The main Elm module (RobotDashboard)

Boston Elixir

Views

Views generate the HTML that presents the current state of the model

And sets up user triggered actions as effects

Status/View.elm

Page 29: Building a robot dashboard with Phoenix and Elmfiles.meetup.com/18220015/robot_dashboard_phoenix_elm.pdf · Boston Elixir Elm runtime Phoenix signals Elm The main Elm module (RobotDashboard)

Boston Elixir

Views

The App view function displays the entire dashboard

• by delegating to the view function of each component

• and wrapping each component's “address” with its own distinguishing action tag

App/View.elm

Page 30: Building a robot dashboard with Phoenix and Elmfiles.meetup.com/18220015/robot_dashboard_phoenix_elm.pdf · Boston Elixir Elm runtime Phoenix signals Elm The main Elm module (RobotDashboard)

Boston Elixir

Elm runtime

Elixir/OTP

Elm queries Phoenix

Via a REST API

• Configured in Ev3.Router

• /robot/togglePaused (post)● Toggles the robot between

fainting and reviving

● Delegated to Ev3.RobotController

● Who sends a “toggle_paused” event to the CNS

• /robot/paused (get)● Ev3.RobotController asks the

CNS

● About the fainted vs. revived status of the robot

Elm

PhoenixEndpoint

Router

RobotController

CNS

Dashboard

Task

Page 31: Building a robot dashboard with Phoenix and Elmfiles.meetup.com/18220015/robot_dashboard_phoenix_elm.pdf · Boston Elixir Elm runtime Phoenix signals Elm The main Elm module (RobotDashboard)

Boston Elixir

Phoenix signals Elm

A Phoenix channel (RobotChannel) is joined by the Dashboard

CNS dispatches event notifications to its event handlers

• ChannelsHandler is one of the event handlers

• It converts events of interest into broadcasts to the channel the Dashboard has joined

Page 32: Building a robot dashboard with Phoenix and Elmfiles.meetup.com/18220015/robot_dashboard_phoenix_elm.pdf · Boston Elixir Elm runtime Phoenix signals Elm The main Elm module (RobotDashboard)

Boston Elixir

Elm runtime

Phoenix signals Elm

The main Elm module (RobotDashboard) defines ports for incoming signals

• Each port specifies a signal of a given type

Each kind of Phoenix channel event (broadcasted from ChannelsHandler) is associated (in app.js) with an Elm port

• There's an event for reporting fainting, another event for new percepts, new motives etc.

• The payload of a broadcasted event must match the Elm data type of the targeted Elm port

• Data format translation (Elixir map to

JSON to Elm record) is automatic

Elixir/OTP

Elm

PhoenixUserSocket

RobotChannel

ChannelsHandler

CNS

Dashboard

Port

Page 33: Building a robot dashboard with Phoenix and Elmfiles.meetup.com/18220015/robot_dashboard_phoenix_elm.pdf · Boston Elixir Elm runtime Phoenix signals Elm The main Elm module (RobotDashboard)

Boston Elixir

Loving it!

Phoenix + Elm > peanut butter + jam

Elm changed the way I think about code

● Functional Reactive Programming● Strict (but smart) typing● Side-effect-free coding● No runtime errors

At first, the Elm Architecture felt like a strange way of doing Web apps

● Signals, tasks, effects and ports● JSON decoding● UI as a signal of HTML

But now I am hooked

Page 34: Building a robot dashboard with Phoenix and Elmfiles.meetup.com/18220015/robot_dashboard_phoenix_elm.pdf · Boston Elixir Elm runtime Phoenix signals Elm The main Elm module (RobotDashboard)

Boston Elixir

And it's about to get even better

March 11, 2016 – Erlang Factory SF

Chris McCord (Phoenix) and Evan Czaplicki (Elm) announced they will collaborate to better integrate Phoenix and Elm

Chris

Evan

https://www.youtube.com/watch?v=XJ9ckqCMiKk

Page 35: Building a robot dashboard with Phoenix and Elmfiles.meetup.com/18220015/robot_dashboard_phoenix_elm.pdf · Boston Elixir Elm runtime Phoenix signals Elm The main Elm module (RobotDashboard)

Boston Elixir

Resources for

Elm

• elm-lang.org

• elm-tutorial.org

• The Pragmatic Studio online courses● Elm: Building Reactive Web Apps

● Elm: Signals, Mailboxes & Ports

Phoenix

• phoenixframework.org

• Programming Phoenix (book)

Elm-Phoenix integration

• Cultivate's blog series

• Phoenix channels doc

+

Page 36: Building a robot dashboard with Phoenix and Elmfiles.meetup.com/18220015/robot_dashboard_phoenix_elm.pdf · Boston Elixir Elm runtime Phoenix signals Elm The main Elm module (RobotDashboard)

Boston Elixir

I blog about all this

http://jfcloutier.github.io/robotex/

Page 37: Building a robot dashboard with Phoenix and Elmfiles.meetup.com/18220015/robot_dashboard_phoenix_elm.pdf · Boston Elixir Elm runtime Phoenix signals Elm The main Elm module (RobotDashboard)

Boston Elixir

Next steps

Two robots!

• Sharing perceptions, spreading motives, influencing behaviors

• How do societies of mind form a society of minds?

Moving to Nerves Project + ev3dev

• Smaller memory footprint for running Elixir (and Phoenix) on the EV3

• Coming soon

Page 38: Building a robot dashboard with Phoenix and Elmfiles.meetup.com/18220015/robot_dashboard_phoenix_elm.pdf · Boston Elixir Elm runtime Phoenix signals Elm The main Elm module (RobotDashboard)

Boston Elixir

Thank you all!

I organize the Portland (Maine) Erlang & Elixir meetup

[email protected]

• Twitter: jfcloutier

• Github: https://github.com/jfcloutier/ev3