Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
Last revisionBoth sides next revision
research:software:lrp [2016/07/16 18:16] jfabryresearch:software:lrp [2017/09/11 20:50] – [Downloads] mcampusa
Line 6: Line 6:
 LRP is open source, download instructions [[research:software:lrp#Downloads|are below]], [[https://github.com/jfabry/LiveRobotProgramming|example code]] can be found online and there is a public [[https://github.com/jfabry/LiveRobotProgramming/issues|bug tracker]]. LRP is open source, download instructions [[research:software:lrp#Downloads|are below]], [[https://github.com/jfabry/LiveRobotProgramming|example code]] can be found online and there is a public [[https://github.com/jfabry/LiveRobotProgramming/issues|bug tracker]].
  
-NEWS: +We all like videos of robots, right? Here are some of LRP on a few different robots for your viewing pleasure. 
-  * We had some fun with our big PR2 robot and made a few videos of LRP controlling it. [[https://www.youtube.com/watch?v=rtSKH-FBbzA|Pick and place interaction with speech control]] and [[https://www.youtube.com/watch?v=fl21wsb_a3c|How does a PR2 move through a door]] are worth your time.+  * [[https://www.youtube.com/watch?v=2bKEEVfuMic|Moving the Duckiebot platform using LRP]] (This uses ROS to control the robot.) 
 +  * [[https://www.youtube.com/watch?v=fl21wsb_a3c|How does a PR2 move through a door with LRP]]? (This uses ROS to control the robot.
 +  * [[https://www.youtube.com/watch?v=ENmuGU4gBh4|Flying a Parrot AR.Drone 2]], using AR tags. (This uses the Parrot API to control the drone.) 
 +  * [[https://www.youtube.com/watch?v=q1jGDtaW41U|Making a NAO robot follow a ball]]. (This uses the NAO API to control the robot.) 
 +  * [[https://www.youtube.com/watch?v=rtSKH-FBbzA|PR2 pick and place interaction with speech control]]. (This uses ROS to control the robot.) 
 + 
 +**NEWS**: 
 +  * [[http://pharo.org/news/AR.Drone|Parrot AR.Drone 2 support is finished!]] 
 +  * [[http://pharo.org/news/Nao-robot|A first version of NAO support is out!]]
   * Journal paper defining LRP, the functioning of the interpreter and bridges to robot API accepted for Science of Computer Programming, a [[http://pleiad.dcc.uchile.cl/papers/2016/campusanoAl-scp16.pdf|preprint is available]].   * Journal paper defining LRP, the functioning of the interpreter and bridges to robot API accepted for Science of Computer Programming, a [[http://pleiad.dcc.uchile.cl/papers/2016/campusanoAl-scp16.pdf|preprint is available]].
   * NIER Paper on visualizing robotic sensors accepted at [[http://vissoft.dcc.uchile.cl/|VISSOFT 2015]], a [[http://pleiad.dcc.uchile.cl/papers/2015/campusanoFabry-vissoft2015.pdf|preprint is available]].   * NIER Paper on visualizing robotic sensors accepted at [[http://vissoft.dcc.uchile.cl/|VISSOFT 2015]], a [[http://pleiad.dcc.uchile.cl/papers/2015/campusanoFabry-vissoft2015.pdf|preprint is available]].
Line 20: Line 28:
 </html> </html>
  
-As LRP is not bound to a specific robot infrastructure, bridges to a given infrastructure are add-ons to the language. The language can therefore also be used 'simply' as a nested state machine live programming language! Currently LRP provides a bridge to [[http://www.ros.org|ROS]] and to the Lego Mindstorms EV3 via [[http://www.phratch.com/jetstorm|JetStorm]]. A bridge to the [[http://www.parrot.com/usa/products/ardrone-2/|Parrot AR.Drone 2]] is under development and will be released Real Soon Now ;-).+As LRP is not bound to a specific robot infrastructure, bridges to a given infrastructure are add-ons to the language. The language can therefore also be used 'simply' as a nested state machine live programming language! Currently LRP provides a bridge to [[http://www.ros.org|ROS]]to the Lego Mindstorms EV3 via [[http://www.phratch.com/jetstorm|JetStorm]] and to the [[http://www.parrot.com/usa/products/ardrone-2/|Parrot AR.Drone 2]].
  
 LRP is implemented in [[http://pharo.org|Pharo Smalltalk]], so basic knowledge of Smalltalk is required to be able to write useful code. But don't panic, Pharo itself comes with a set of tutorials that are sufficient for being able to use LRP. LRP is implemented in [[http://pharo.org|Pharo Smalltalk]], so basic knowledge of Smalltalk is required to be able to write useful code. But don't panic, Pharo itself comes with a set of tutorials that are sufficient for being able to use LRP.
Line 46: Line 54:
   (spawn esc tick)   (spawn esc tick)
  
-States may also contain actions: an on entry action (''onentry''), an on exit action (''onexit'') and a running action (''running''). Actions are Smalltalk blocks. When a state becomes active, its on entry action is executed once, completely. When the state stops being active, its on exit action is executed once, completely. While the state is active, its running action is executed as the main part of the interpretation loop. In other words, the block is executed repeatedly, and between each execution of the block the events are checked. ((When a state with a nested machine stops being active, the nested machine is stopped and discarded. As part of this process, the on exit action in the active state of this nested machine is performed after any machines nested in that state are stopped and discarded (and so on recursively).))+States may also contain actions: an on entry action (''onentry''), an on exit action (''onexit'') and a running action (''running''). Actions are Smalltalk blocks. When a state becomes active, its on entry action is executed once, completely. When the state stops being active, its on exit action is executed once, completely. While the state is active, its running action is executed as the main part of the interpretation loop. In other words, the block is executed repeatedly, and between each execution of the block the events are checked. 
  
 A machine can also define variables. Global variables may also be defined, outside of the root machine. Variables must be given a value when they are defined, the value is the result of evaluating a Smalltalk block. This block has in scope all variables that are lexically in scope. All actions (i.e. ''onentry'', ''onexit'', ''running'' blocks) may read, send messages to, and set all variables in their lexical scope. A machine can also define variables. Global variables may also be defined, outside of the root machine. Variables must be given a value when they are defined, the value is the result of evaluating a Smalltalk block. This block has in scope all variables that are lexically in scope. All actions (i.e. ''onentry'', ''onexit'', ''running'' blocks) may read, send messages to, and set all variables in their lexical scope.
Line 121: Line 129:
 </html> </html>
  
 +==== Advanced Features ====
 +
 +=== Nested Machines ===
 +
 +As LRP is a nested state machine language, a state of a machine may contain (several) complete state machine(s), whose states may again contain a machine, and so on. Machines can be spawned when the state is entered by having the ''onentry'' statement  contain a ''spawn'' statement instead of an action block. The machine specified in such a spawn can be any machine that is in lexical scope. This allows the machine to be spawned to be defined in the spawning state or any parent state, recursively up to the root (including other machines defined at root level). 
 +
 +<note important>Note that if there is **no** ''onentry'' spawn, a machine that is contained lexically in the state is **not** executed.</note> 
 +
 +When a state with a nested machine stops being active, the nested machine is stopped and discarded. As part of this process, the on exit action in the active state of this nested machine is performed after any machines nested in that state are stopped and discarded (and so on recursively).
 +
 +A brief (contrived) example is as follows:
 +<code>
 +(machine root
 + (state r1
 + (machine nest1 
 + (state n1
 + (machine nest2 (state n1n2))
 + (onentry (spawn nest2 n1n2))
 + )
 + (ontime 500 n1->n2)
 + (state n2
 + (machine nest3 (state n2n3))
 + (onentry (spawn nest3 n2n3))
 + )
 + (state n3)
 + (ontime 500 n2->n3))
 + (onentry (spawn nest1 n1))
 + )
 + (state r2)
 + (ontime 2000 r1->r2)
 + (ontime 500 r2->r1)
 +)
 +(spawn root r1)
 +</code>
 +
 +=== Concurrency ===
 +
 +It is possible to have multiple machines running at the same time, i.e. to have multiple machines each with an active state, without these machines being nested. To achieve this, multiple ''spawn'' statements are specified, either at top level or as ''onentry'' actions of a state. Concurrency obeys the following rules:
 +  * If a spawn statement specifies a machine that is already running, i.e. that already has an active state, the spawn fails with an error.
 +  * exiting a state that has multiple nested machines concurrently running means exiting all of these machines
 +  * removing a top-level spawn does NOT stop the machine that was spawned
 +  * adding or removing a spawn of a state means changing the state. So if the state is active (possibly having multiple nested machines running) the program is restarted.
 +
 +The scheduling of machine execution is fair and predictable:
 +  * all top level spawned machines perform one interpretation step for each interpreter step. This happens sequentially and the  order is the lexical order of the spawn statements.
 +  * all nested machines perform one interpretation step for each interpretation step of the state. This happens sequentially and the order is the lexical order of the spawn statements. Note that this implies recursion when an active state of a nested machine has concurrent nested state machines.
 +
 +Put succinctly, interpretation of multiple running machines is equal to a depth-first traversal of the running machines tree.
 +
 +There are two brief (contrived) examples:
 +<code>
 +(machine m
 + (state s) (state t)
 + (ontime 1500 s->t) (ontime 1500 t->s)
 +)
 +(machine n
 + (state a) (state b) (state c)
 + (ontime 2000 a->b) (ontime 2000 b->c) (ontime 2000 c->a)
 +)
 +(spawn m s)
 +(spawn n a)
 +</code>
 +<code>
 +(machine m
 + (state s) (state t)
 + (ontime 1500 s->t) (ontime 1500 t->s)
 +)
 +(machine n
 + (state a) (state b) (state c)
 + (ontime 2000 a->b) (ontime 2000 b->c) (ontime 2000 c->a)
 +)
 +(machine o
 + (state p
 + (onentry (spawn m s))
 + (onentry (spawn n a)))
 +)
 +(spawn o p)
 +</code>
 +
 +
 +=== Exit transitions ===
 +
 +In a nested machine it is possible to define transitions that go to a state of the parent machine, effectively exiting the nested machine. Such transitions are like normal transactions, except that their keyword is ''exit'' and the destination state should be a state of the parent machine. Note that exit transitions are in fact syntactic sugar.
 +
 +A simple example is as follows. As soon as the ''out'' variable is set to ''true'', the nested machine is exit.
 +<code>
 +(machine root
 + (var out := [false])
 + (state one
 + (machine nested
 + (state onen)
 + (exit goout onen->two)
 + (event goout [out]))
 + (onentry (spawn nested onen))
 + )
 + (state two)
 +)
 +(spawn root one)
 +</code>
 +
 +=== Eventless transitions ===
 +
 +It can become tedious for transitions to need an event as a trigger, since it requires the definition of an event as a separate statement. This is especially tedious when the transition is the only that references that event. To ease this tedium, transitions also accept a block instead of an event name. This block should return true for the transition to trigger. 
 +
 +Eventless transitions are in fact syntactic sugar: an event is generated and added to the machine, with as action block the block that was specified in the transition, and the transition instead then refers to that event.
 +
 +=== User interface: Transition to and Jump to ===
 +
 +The LRP user interface allows for the user to force a machine in a given state. By right-clicking on a state in the visualisation a menu appears, with the option to ''transition to'' or ''jump to''. The former acts as if a transition is added from the currently active state to the selected state, and this transition is removed immediately after it is taken. The latter also transitions to the given state, however **without** running the ''onexit'' and ''onentry'' actions of all affected states. (Recall that if a state has a nested machine, its active state ''onexit'' actions are normally also executed.)
 +
 +Transition to and jump to also combine with concurrency (see above for concurrency): if this machine and none of its parents is running, the machine is spawned as a top-level spawn. If it (or its parents) is running, the active state of that running machine is considered as the state from which the transition or jump starts. 
 ==== Downloads ==== ==== Downloads ====
  
Line 162: Line 281:
  
 Next time the LRP interpreter is opened the ROS bridge UI will open, asking for the name of the class that represents the current package.  Next time the LRP interpreter is opened the ROS bridge UI will open, asking for the name of the class that represents the current package. 
 +
 +If you have problems installing PhaROS, you can bypass the main installation by downloading only the PhaROS API for Pharo.
 +  Gofer it
 +    smalltalkhubUser: 'CAR' project: 'PhaROS';
 +    configuration;
 +    load
 +
 +After installing PhaROS, you can install the LRP ROS bridge (see above).
 +
 +=== Parrot AR.Drone Support ===
 +
 +The Parrot AR.Drone 2 is also supported in LRP. To use it, get the Pharo API from [[http://smalltalkhub.com/#!/~CaroHernandez/ArDronePharo]], the documentation of the API is also at this repository and the LRP bridge can also be found there.
 +
 +Example LRP code for the drone [[https://github.com/carolahp/ARDroneLRP-Tests|is available on GitHub]].
  
 === Lego Mindstorms EV3 Support === === Lego Mindstorms EV3 Support ===