Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

This brief guide introduces the main components and concepts of this API and provides some code samples that can be used as a starting point.

Requirements

The Python-SIC connector requires Python 3 (with tkinter enabled).

...

Make sure Python can compile native extensions (e.g. for Windows see https://www.scivision.dev/python-windows-visual-c-14-required).

...

You can use a Python editor of your choice (Pycharm for example).

Abstract SIC Connector

Introduction

The first main component is the AbstractSICConnector class. It requires the IP address of the SIC with which it sets up the connection to the SIC and enables you to send action commands to the robot and receive data generated by either the robot or the SIC itself. The data contains events (e.g. when a button is pressed ‘LeftBumperPressed' or when an action is finished 'WakeUpDone’) or the results of certain actions (e.g. a recognized intent after a speech recognition attempt).

Usage

The AbstractSICConnector class is abstract, meaning that itself does not do anything with the incoming data. To process the incoming data you can implement your own concrete SIC Connector class by inheriting the AbstractSICConnector class and overriding the empty event handlers.

Example

In the below MyConnector example, you see that it uses the AbstractSICConnectorclass as a parent, inheriting all its methods. Two things have been added. First of all, the on_robot_event method is overridden to print all the events generated by the robot. Secondly, a run method is added that sends actions to the SIC.

...

Table of Contents

Table of Contents
minLevel1
maxLevel1

State Machines Interaction Flows

Implementing a social interaction flow will go more efficiently if your code could have a similar structure to a graph/flowchart. Each step in the interaction is going from one state to another, based on the input from an end-user and the goals of the robot.

To structure your code using state and state transitions you can use the state machine design pattern. See Gkasdrogkas (2020), Nath (2019) or Shalyto et al. for a more extensive explanation of what they are.

Using this approach you can create a whole chain of states, neatly separating each interaction step in different states and methods. It does not have to be a linear sequence. You can create branches and cycles, depending on the indented interaction flow.

The most important component of state machines are the state transitions.

  • define what triggers a transition (e.g.: a button press)

  • define prerequisites of a state transition (e.g.: to get from the sleep to the awake state, a robot first needs to stand up)

Usage

In order to facilitate the implementation of state machines, the library pytransitions ca be used. It is “a lightweight, object-oriented finite state machine implementation in Python with many extensions”. Read their guide to learn more.

Example

Let’s look at an example of how to use it together with the SIC Python API. The example is comprised of a basic interaction flow. In this interaction flow, the robot starts by being asleep, wakes up, introduces itself and gets acquainted with the person and then says goodbye.

It starts with creating a model class for a robot that has states and link it to a state machine:

Code Block
breakoutModewide
languagepy
from transitions import Machine

class ExampleRobot(object):
   
   states = ['asleep', 'awake', 'introduced', 'got_acquainted', 'goodbye']

   def __init__(self, server_ip):
      self.machine = super(MyConnector, self).__init__(server_ip)Machine(model=self, states=ExampleRobot.states, initial='asleep')
      self.machine.add_transition(trigger='start', source='asleep', dest='awake',
                 def run(self):         self.start()
  before='wake_up', after='introduce')
      self.setmachine.add_language('en-US')transition(trigger='introduce', source='awake', dest='introduced',
           sleep(1)  # wait for the language to change         self.say('Hello, world!before='introduction', after='get_acquainted')
      ...
 sleep(3)  # wait for the
robot to be done speakingdef wake_up(toself) see the relevant prints)-> None:
        self.stop()sic.set_language('en-US')
      def on_robot_event(self, event):  self.sic.wake_up()
        print(eventself.sic.run_loaded_actions()

robot = ExampleRobot()
robot.start() # Runcauses state thetransition applicationfrom my_connectorasleep = MyConnector(server_ip='127.0.0.1')
my_connector.run()to awake
  1. define all the states of the state machine (line 5)

  2. initialise the state machine with the model, state and initial state (line 8)

  3. add transitions between states (line 9) - if we have an instantiation of the ExampleRobot class we can now call the start method (trigger) to cause a transition from the initial asleep state (source) the the awake state (destination):

    • the trigger to a transition is the method that causes the transition

      • in this case, the robot will wake up upon the call of the start method (line 21)

    • the source of a transition is the previous state in which the state machine was

      • in this case, “asleep”

    • the destination of a transition is the state to which the transition directs the state machine is directed

      • in this case, “awake”

    • before trigger of a transition is a statement to call a method before the transition happens

      • in this case, method wake_up (line 15)

    • after trigger of a transition is a statement to trigger after a transition happens

      • in this case, “introduce” becomes a trigger to the next transition “introduced” (line 11)

      • note: Often there are no external triggers to trigger a state transition in the human-robot interaction flow. For example, when the robot is awake and ready it should automatically move to a next state. Adding an after parameter to the next transition as a trigger would address this issue

For a complete working example see https://bitbucket.org/socialroboticshub/examples/src/main/python/4_state_machine.py .