Aldebaran documentation What's new in NAOqi 2.4.3?

ALTouch

NAOqi Sensors & LEDs - Overview | API


What it does

The ALTouch module generates the event TouchChanged() whenever the robot is touched.

The event TouchChanged() gives you a list of AL::ALValue with a body part and a boolean for the touch status.

For example:

  • [[“Head/Touch/Middle”, True], [“ChestBoard/Button”, True]]
  • [[“Head/Touch/Middle”, False]]
  • [[“LArm”, True], [“RHand”, False]]

How it works

The aim of these sensors is to determine whether the robot is touched. It’s a bistable behavior, an event is raised when for example the head is touched with the value True then an other one when the head is not touch anymore with the value False.

For the button [tactile, bumper, chest ...], the value is read in the ALMemory and if the status changed, an event is raised. For body parts that do not have capacitive sensors, touch is detected by a difference between joint angle commands and sensor.

../../_images/touched.png

Making a Python module - Reacting to Touch

The example below is a NAOqi Python module that reacts to touch events.

sensors_touch.py

# -*- encoding: UTF-8 -*-

"""Example: Say `My {Body_part} is touched` when receiving a touch event"""

import qi
import argparse
import functools
import sys

class ReactToTouch(object):
    """ A simple module able to react
        to touch events.
    """
    def __init__(self, app):
        super(ReactToTouch, self).__init__()

        # Get the services ALMemory, ALTextToSpeech.
        app.start()
        session = app.session
        self.memory_service = session.service("ALMemory")
        self.tts = session.service("ALTextToSpeech")
        # Connect to an Naoqi1 Event.
        self.touch = self.memory_service.subscriber("TouchChanged")
        self.id = self.touch.signal.connect(functools.partial(self.onTouched, "TouchChanged"))

    def onTouched(self, strVarName, value):
        """ This will be called each time a touch
        is detected.

        """
        # Disconnect to the event when talking,
        # to avoid repetitions
        self.touch.signal.disconnect(self.id)

        touched_bodies = []
        for p in value:
            if p[1]:
                touched_bodies.append(p[0])

        self.say(touched_bodies)

        # Reconnect again to the event
        self.id = self.touch.signal.connect(functools.partial(self.onTouched, "TouchChanged"))

    def say(self, bodies):
        if (bodies == []):
            return

        sentence = "My " + bodies[0]

        for b in bodies[1:]:
            sentence = sentence + " and my " + b

        if (len(bodies) > 1):
            sentence = sentence + " are"
        else:
            sentence = sentence + " is"
        sentence = sentence + " touched."

        self.tts.say(sentence)


if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("--ip", type=str, default="127.0.0.1",
                        help="Robot IP address. On robot or Local Naoqi: use '127.0.0.1'.")
    parser.add_argument("--port", type=int, default=9559,
                        help="Naoqi port number")

    args = parser.parse_args()
    try:
        # Initialize qi framework.
        connection_url = "tcp://" + args.ip + ":" + str(args.port)
        app = qi.Application(["ReactToTouch", "--qi-url=" + connection_url])
    except RuntimeError:
        print ("Can't connect to Naoqi at ip \"" + args.ip + "\" on port " + str(args.port) +".\n"
               "Please check your script arguments. Run with -h option for help.")
        sys.exit(1)
    react_to_touch = ReactToTouch(app)
    app.run()