-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Generated gh-pages for commit 62d767e
Author: Dennis Holzmann <[email protected]> add examples
- Loading branch information
Showing
37 changed files
with
1,811 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
============ | ||
Compound States | ||
============ | ||
|
||
States can consist of multiple other states. These states are grouped: | ||
|
||
.. code-block:: xml | ||
<state id="DoCoolStuff" initial="example.Succeeder"> | ||
<!-- we can also define transitions here --> | ||
<!-- The parent states transition gets checked if none of the childs matches --> | ||
<transition event="Succeeder.*" target="Fatal"/> | ||
<state id="example.Succeeder"> | ||
<transition event="Succeeder.success" target="example.Succeeder#again"/> | ||
</state> | ||
<state id="example.Succeeder#again"> | ||
<transition event="Succeeder.success" target="example.Nothing"/> | ||
</state> | ||
</state> | ||
<state id="example.Nothing"> | ||
<!-- this is a easy reference to transition too --> | ||
<transition event="Nothing.fatal" target="DoCoolStuff"/> | ||
</state> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
============ | ||
Memory Slots | ||
============ | ||
|
||
Skills | ||
------ | ||
|
||
Slots are used to store data for other skills/states to use. | ||
|
||
Take a look at the SlotWriter and SlotReader skill: | ||
|
||
.. code-block:: kotlin | ||
class SlotWriter : AbstractSkill() { | ||
private var tokenSuccess: ExitToken? = null | ||
private var slot: MemorySlotWriter<String>? = null | ||
override fun configure(configurator: ISkillConfigurator) { | ||
tokenSuccess = configurator.requestExitToken(ExitStatus.SUCCESS()) | ||
slot = configurator.getWriteSlot("StringToWriteTo", String::class.java) | ||
} | ||
override fun init(): Boolean { | ||
return true | ||
} | ||
override fun execute(): ExitToken { | ||
slot!!.memorize("Hello World") | ||
return tokenSuccess!! | ||
} | ||
override fun end(curToken: ExitToken): ExitToken { | ||
return curToken | ||
} | ||
} | ||
.. code-block:: kotlin | ||
class SlotReader : AbstractSkill() { | ||
private var tokenSuccess: ExitToken? = null | ||
private var slot: MemorySlot<String>? = null | ||
private var read: String? = "" | ||
override fun configure(configurator: ISkillConfigurator) { | ||
tokenSuccess = configurator.requestExitToken(ExitStatus.SUCCESS()) | ||
slot = configurator.getReadSlot<String>("StringIAmReading", String::class.java) | ||
} | ||
override fun init(): Boolean { | ||
read = slot!!.recall<String>() ?: return false | ||
return true | ||
} | ||
override fun execute(): ExitToken { | ||
logger.info("current data: $read") | ||
return tokenSuccess!! | ||
} | ||
override fun end(curToken: ExitToken): ExitToken { | ||
return curToken | ||
} | ||
} | ||
Both want to access a slot which stores strings. | ||
The SlotWriter requests access to the slot with the key "StringToWriteTo" in which he wants to write The string "Hello World": | ||
|
||
.. code-block:: kotlin | ||
slot = configurator.getWriteSlot("StringToWriteTo", String::class.java) | ||
// ... some other code ... | ||
override fun execute(): ExitToken { | ||
slot!!.memorize("Hello World") | ||
return tokenSuccess!! | ||
} | ||
The SlotReader on the other hand requests a slot to read a string from. | ||
The read data is then simply printed: | ||
|
||
.. code-block:: kotlin | ||
slot = configurator.getReadSlot<String>("StringIAmReading", String::class.java) | ||
// ... some other code ... | ||
override fun init(): Boolean { | ||
read = slot!!.recall<String>() ?: return false | ||
return true | ||
} | ||
override fun execute(): ExitToken { | ||
logger.info("current data: $read") | ||
return tokenSuccess!! | ||
} | ||
State Machine | ||
------------- | ||
|
||
Now that we have the skills to read and write, we need to integrate them into our state machine. | ||
The skills require slots with the keys "StringToWriteTo" and "StringIAmReading". | ||
We have to assign a path for the slots in the state machine. | ||
The paths should be the same, so that the writer writes "hello World" and the reader then reads the same string. | ||
The path for the slots have to be defined in the datamodel. The data id needs to be "#_SLOTS". | ||
There, we can define the path for each slot key. | ||
|
||
.. code-block:: xml | ||
<datamodel> | ||
<data id="#_STATE_PREFIX" expr="'de.unibi.citec.clf.bonsai.skills.'"/> | ||
<!-- slots are used to store data for other skills/states to use --> | ||
<!-- we have to define the path for each used slot --> | ||
<data id="#_SLOTS"> | ||
<slots> | ||
<slot key="StringToWriteTo" state="example.SlotWriter" xpath="/path"/> | ||
<slot key="StringIAmReading" state="example.SlotReader" xpath="/path"/> | ||
</slots> | ||
</data> | ||
</datamodel> | ||
.. warning:: | ||
Keep in mind that the slot key in the datamodel of the state machine needs to be the same as in the skill! | ||
|
||
With the keys being setup correctly, the slot writer will write the string to the /path path and the reader will read from it. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
============ | ||
Parameters and Variables | ||
============ | ||
|
||
Parameters | ||
---------- | ||
|
||
Some skills require further parameters that you don't necessarily want to write in a slot. | ||
For that case, the state machine enables propagating parameters to the skill. | ||
|
||
For example, the skill ParameterHaver defines two parameters "value" and "optional": | ||
|
||
.. code-block:: kotlin | ||
class ParameterHaver : AbstractSkill() { | ||
private var value = "" | ||
private var optional = false | ||
//... | ||
override fun configure(configurator: ISkillConfigurator) { | ||
// ... | ||
value = configurator.requestValue("value") | ||
optional = configurator.requestOptionalBool("option", optional) | ||
} | ||
// ... | ||
} | ||
Each Parameters needs to be requested by the configurator. | ||
The "optional" parameter here is an optional bool value. | ||
|
||
When we are using this skill in the state machine, we can provide the skill with these parameters. | ||
The parameter "value" *must* be provided in the state machine. The parameters have to be set in a datamodel **within** the state: | ||
|
||
.. code-block:: xml | ||
<state id="example.ParameterHaver"> | ||
<!-- skill parameter are read from the state datamodel --> | ||
<datamodel> | ||
<data id="value" expr="'Hello'"/> | ||
</datamodel> | ||
<transition event="ParameterHaver.*" target="example.ParameterHaver#option"/> | ||
</state> | ||
<state id="example.ParameterHaver#option"> | ||
<datamodel> | ||
<data id="value" expr="'World'"/> | ||
<data id="option" expr="true"/> | ||
</datamodel> | ||
<transition event="ParameterHaver.*" target="End"/> | ||
</state> | ||
.. warning:: | ||
Make sure to use extra quotes for strings! ``<data id="value" expr="'Hello'"/>``. | ||
Booleans and numbers do not need the extra quotes. | ||
|
||
|
||
Variables | ||
--------- | ||
|
||
Variables are not specific for each state but rather for the whole state machine. As such, they are defined in the datamodel of the state machine: | ||
|
||
.. code-block:: xml | ||
<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" initial="example.ParameterHaver"> | ||
<datamodel> | ||
<data id="hellosToSpeak" expr="3"/> | ||
</datamodel> | ||
<state id="example.ParameterHaver"> | ||
<datamodel> | ||
<data id="value" expr="'@hellosToSpeak'"/> | ||
</datamodel> | ||
<transition event="ParameterHaver.*" target="End" /> | ||
</state> | ||
</scxml> | ||
The ParameterHaver skill gets the "hellosToSpeak" variable assigned as parameter. | ||
|
||
.. warning:: | ||
Since the "value" parameter needs to be a string, we need to add quotes and a @ to get the variable as string: | ||
``<data id="value" expr="'@hellosToSpeak'"/>`` | ||
|
||
During transitions we can execute SCXML actions. | ||
The variables can be changed by assigning them a new value using the "assign" action: | ||
|
||
.. code-block:: xml | ||
<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" initial="example.ParameterHaver"> | ||
<datamodel> | ||
<data id="hellosToSpeak" expr="3"/> | ||
</datamodel> | ||
<state id="example.ParameterHaver"> | ||
<datamodel> | ||
<data id="value" expr="'Hello'"/> | ||
</datamodel> | ||
<transition event="ParameterHaver.*" target="example.ParameterHaver" > | ||
<assign name="hellosToSpeak" expr="hellosToSpeak - 1"/> | ||
</transition> | ||
</state> | ||
</scxml> | ||
With variables, we also can introduce conditions in transitions. For example, as long as "hellosToSpeak" is greater than 1, we want ParameterHaver to be executed again. | ||
This can be done by adding ``cond="hellosToSpeak > 1"`` in the transition. Another transition without any conditions is then defined at the end: | ||
|
||
.. code-block:: xml | ||
<state id="example.ParameterHaver"> | ||
<datamodel> | ||
<data id="value" expr="'Hello'"/> | ||
</datamodel> | ||
<transition event="ParameterHaver.*" cond="hellosToSpeak > 1" target="example.ParameterHaver"> | ||
<assign name="hellosToSpeak" expr="hellosToSpeak - 1"/> | ||
</transition> | ||
<transition event="ParameterHaver.*" target="End" /> | ||
</state> | ||
On Entry/Exit | ||
-------- | ||
|
||
We can also use the on_entry/on_exit actions of the state to assign some values to a variable. | ||
The on_entry action here decrements the "hellosToSpeak" variable each time the state machine transitions back to the state: | ||
|
||
.. code-block:: xml | ||
<state id="example.ParameterHaver"> | ||
<datamodel> | ||
<data id="value" expr="'Hello'"/> | ||
</datamodel> | ||
<onentry> | ||
<assign name="hellosToSpeak" expr="hellosToSpeak - 1"/> | ||
</onentry> | ||
<transition event="ParameterHaver.*" cond="hellosToSpeak > 0" target="example.ParameterHaver" /> | ||
<transition event="ParameterHaver.*" target="End" /> | ||
</state> |
Oops, something went wrong.