Skip to content

Tutorial 3: Actions

Robert edited this page Apr 4, 2023 · 20 revisions

Note: This tutorial assumes that you are familiar with the concept of Actions and UMRFs in TeMoto.

Note: All examples shown in this tutorial can be found and replicated via Temoto Tutorials repository.


The basis for an action can be easily generated via TeMoto Action Assistant. Since the structure of an action is defined by its UMRF, the TeMoto Action Assistant provides the graphical interface for creating an UMRF. Once you are happy with the UMRF, a basis for action implementation package is generated, including a c++ source file. Each action is implemented as a ROS package.

Create a TeMoto Action

1) Launch the TeMoto action assistant GUI

roslaunch <my_temoto_config> action_assistant.launch

This should bring up the start screen of the action assistant, depicted in Fig. 1.

TeMoto Action Assistant

Figure 1: Start screen of the TeMoto Action Assistant

Click on "Create New TeMoto Action Package".

2) Create your UMRF

Go to the "UMRF Editor" tab (depicted in Fig. 2). This tab consists of 2 main sections:

  • UMRF Viewer section, which visually shows the structure of the UMRF.
  • Item Editor section, which allows to edit the currently active item in the UMRF Viewer.

UMRF Editor

Figure 2: UMRF Editor tab

Each action is represented with an interactive circle in the canvas, that you can drag & drop, or simply select to change its parameters in the Item Editor section.

  • Modify the name by clicking on the "Name:" item in the UMRF viewer and changing the name in the item editor. In the given example, let's call it "add_numbers"
  • Add new input parameter by right-clicking on the "Input Parameters" item and selecting "ADD parameter".

Add Parameters

Figure 3: UMRF Editor Adding parameters

There is a dropdown menu with a list of pre-defined parameters that you can use, or it is also possible to create your own parameter structure in the custom tab. For now, select "my_number (number)" and click "ok".

  • Select the newly created parameter and change its name to "input_1" and make sure the type is "number".
  • Add another input parameter and change its name to "input_2" and its type to "number".
  • Add an output parameter and change its name to "output_1" and its type to "number".

The UMRF is now done (end result shown in Fig. 4).

Final UMRF

Figure 4: UMRF of add_numbers action with input and output parameters

3) Generate the action package

Go to the "Generate Actions" tab (depicted in Fig. 5).

  • Since this tutorial assumes that the Action Assistant was opened via TeMoto workspace (see the first step in this tutorial), then the directory where the action will be generated is automatically set. If that's not the case then select the directory where the action package is generated.
  • Generate the package by clicking the "Generate" button.

Generate Package

Figure 5: Generate Action tab

Note: Leave the action assistant open, since it is used later in the UMRF Graph section

4) Modify the autogenerated source code

Now navigate to the generated package and open the action source file with your preferred editor. For example:

    cd <my_temoto_config>/temoto_actions/ta_add_numbers/src
    gedit ta_add_numbers.cpp

The action source file contains a bunch of things that are necessary for TeMoto, but we are going to focus on a executeTemotoAction() function. This function is invoked when the action is executed.

Locate the block comment which says "YOUR CODE HERE":

    void executeTemotoAction()
    {
      getInputParameters();

      /* * * * * * * * * * * * * * * * * * * * * * *
      *                          
      *         ===> YOUR CODE HERE <===
      *                          
      * * * * * * * * * * * * * * * * * * * * * * */

      setOutputParameters();
    }

and replace it with code that adds up the numbers and puts the result to the output parameter out_param_output_1

    void executeTemotoAction()
    {
      getInputParameters();

      out_param_output_1 = in_param_input_1 + in_param_input_2;
      TEMOTO_INFO_STREAM("Adding numbers " 
        << in_param_input_1 << " and " 
        << in_param_input_2 << ". Result is " 
        << out_param_output_1);

      setOutputParameters();
    }

Do not modify any of the autogenerated code. Otherwise your action will likely not work properly.

5) Build and test the action

catkin build
# (source your workspace)

# In the first terminal, launch TeMoto 
roslaunch <my_temoto_config> temoto.launch temoto_namespace:=<namespace>

# In the second terminal, invoke the UMRF Graph
roslaunch ta_add_numbers invoke_action.launch wake_word:=<namespace>

Note that the wake_word must match the temoto_namespace defined when launched TeMoto, by default it is <my_temoto_config> (see Tutorial 2: "TeMoto Config" for more details).

The first terminal, where you launched TeMoto, should show:

[my_temoto_config/action_engine/TaAddNumbers_0::executeTemotoAction] Adding numbers 0. and 0. Result is 0.

You can change the input values (denoted as pvf_value) by modifying the test/<name_temoto_action>.umrfg.json under your action package root folder like so:

   {
       "name": "TaAddNumbers",
       "package_name": "ta_add_numbers",
       "suffix": "0",
       "notation": "",
       "effect": "synchronous",
       "input_parameters": {
           "input_1": {
               "pvf_type": "number",
               "pvf_value": 8.4
           },
           "input_2": {
               "pvf_type": "number",
               "pvf_value": 1.2
           }
       },
       "output_parameters": {
           "output_1": {
               "pvf_type": "number"
           }
       }
   }

Save the file and run invoke_action.launch again (no need to recompile the code). The terminal output should now be:

[my_temoto_config/action_engine/TaAddNumbers_0::initializeTemotoAction] Action initialized
[executeUmrfGraph] UMRF graph 'ta_add_numbers' invoked successfully.
[my_temoto_config/action_engine/TaAddNumbers_0::executeTemotoAction] Adding numbers 8.4 and 1.2. Result is 9.6
[my_temoto_config/action_engine/TaAddNumbers_0::~TaAddNumbers] Action instance destructed
[monitoringLoop] Clearing umrf graph 'ta_add_numbers'

Create a UMRF Graph

You can also use the Action Assistant for creating UMRF graphs. You can create as many actions as needed, and connect them in different configurations (sequential, concurrent, cycles).

6.1) Add a new action to the UMRF Editor canvas

There are two ways to insert actions to the UMRF Graph:

  1. Right click on the UMRF Editor canvas and press ADD Action
  2. Type a description on the Graph description field, then highlight the description and right click Annotate as action

Add action

Figure 6: Add action to UMRF Graph

For this example, let's create a new TeMoto action that takes the result of the add_numbers action (output_1), and multiplies it by a factor number.

  • Add a new action and name it "multiply_numbers"
  • Create one input parameters and change its name to "output_1" and make sure the type is "number".

Note that in order to pass values between actions, the name of the input parameter on the child action must match the name of the output parameter of tha parent node.

  • Add another input parameter and change its name to "factor" and its type to "number".
  • Add an output parameter and change its name to "product" and its type to "number".
  • Change the Graph name to "add_and_multiply"
  • In order to connect the actions, select the parent node, then right click over the child node, and click connect. An arrow from the parent node pointing to the child should appear now.

Add action

Figure 7: UMRF Graph with addition and multiplication actions in sequence

  • Click on the "Generate Actions" tab and "Generate" button to create the new Temoto action and the UMRF graph.

Replace the block "YOUR CODE HERE" on "ta_multiply_numbers.cpp" with code that multiplies two numbers and puts the result on the "out_param_product" parameter.

out_param_product = in_param_output_1 * in_param_factor;
TEMOTO_INFO_STREAM( in_param_output_1 << " times " << in_param_factor << " is " << out_param_product);

6.2) Build and test the graph.

catkin build
# (source your workspace)
  • Open the "<my_temoto_config>/umrf_graphs/add_and_multiply.umrfg.json" file
  • Locate the "input_1", and add "pvf_value": 2.0:
    "input_1": {
        "pvf_type": "number",
        "pvf_value": 2.0
    }
  • Do the same for "input_2" and "factor" parameters with values 3.0 and 5.0 respectivelly.
  • Invoke the graph:
# In the first terminal, launch TeMoto
roslaunch <my_temoto_config> temoto.launch temoto_namespace:=<namespace>

# In the second terminal, invoke the UMRF Graph
rosrun temoto_action_engine parser_node <path_to_add_and_multiply.umrfg.json> <temoto_namespace>

Now you should see :

[broadcastStartUmrfGraphCallback] Received a UMRF graph message ...
[executeUmrfGraph] All actions in graph 'add_and_multiply' found.
[executeUmrfGraph] UMRF graph 'add_and_multiply' initialized.
[my_temoto/action_engine/TaAddNumbers_0::initializeTemotoAction] Action initialized
[executeUmrfGraph] UMRF graph 'add_and_multiply' invoked successfully.
[my_temoto/action_engine/TaAddNumbers_0::executeTemotoAction] Adding numbers 2 and 3. Result is 5
[my_temoto/action_engine/TaMultiplyNumbers_0::initializeTemotoAction] Action initialized
[my_temoto/action_engine/TaMultiplyNumbers_0::executeTemotoAction] 5 times 5 is 25
[my_temoto/action_engine/TaAddNumbers_0::~TaAddNumbers] Action instance destructed
[my_temoto/action_engine/TaMultiplyNumbers_0::~TaMultiplyNumbers] Action instance destructed
[monitoringLoop] Clearing umrf graph 'add_and_multiply'

6.3) Add an existing action

In order to add an existing action into the UMRF graph:

  • Type something into the Graph description field
  • Highlight it
  • Right click to get the Annotate as Existing action option
  • Select the desired TeMoto action from the list.

It creates an action in the UMRF viewer canvas with the input and output parameters already set up. This is useful when we want to reuse the same action multiple times.

UMRF Graph

Figure 8: Example of UMRF Graph with manipulation, gripper and navigation actions in sequence.

Clone this wiki locally