Robot face and expressions#
You can control the gaze direction, expressions, and visual appearance of the face and eyes of your robot via several ROS API.
Note
Currently, the face can only be controlled through a ROS interface. In future releases of the SDK, alternative no-code solutions will be offered.
Gaze direction#
The attention-management page contains all the details regarding how to control the robotβs gaze and attention.
Expressions#
The expression of the faces (eyes only for ARI, eyes and mouth for TIAGo Pro) can be changed via the /robot_face/expression topic.
You can either use one of the pre-defined discrete expressions (like happy, confused⦠see list below), or by setting a custom values for valence and arousal, following the circumplex model of emotions.
Code samples#
The following short snippet of Python code loops over several expressions, as show in the animation above:
1import rclpy
2from rclpy.node import Node
3from hri_msgs.msg import Expression
4
5
6class CycleExpressions(Node):
7 def __init__(self):
8 super().__init__('cycle_expressions')
9 self.publisher_ = self.create_publisher(Expression,
10 '/robot_face/expression', 1)
11
12 self.expressions = ['happy', 'sad', 'angry',
13 'surprised', 'neutral', 'furious']
14 self.index = 0
15
16 self.timer_ = self.create_timer(1.0, self.publish_expression)
17
18 def publish_expression(self):
19 msg = Expression()
20 msg.expression = self.expressions[self.index]
21
22 rclpy.logging.get_logger('cycle_expressions').info(
23 'Publishing: "%s"' % msg.expression)
24
25 self.publisher_.publish(msg)
26 self.index = (self.index + 1) % len(self.expressions)
27
28
29if __name__ == '__main__':
30 rclpy.init()
31 node = CycleExpressions()
32 rclpy.spin(node)
33 rclpy.shutdown()
This second example changes the expression continuously, by increasing/decreasing the valence and arousal:
1import rclpy
2from rclpy.node import Node
3from hri_msgs.msg import Expression
4
5
6class CycleValenceArousal(Node):
7 def __init__(self):
8 super().__init__('cycle_valence_arousal')
9 self.publisher_ = self.create_publisher(
10 Expression, '/robot_face/expression', 1)
11
12 self.valence = 0.
13 self.arousal = 0.
14 self.valence_delta = 0.05
15 self.arousal_delta = 0.0
16
17 self.timer_ = self.create_timer(0.2, self.publish_expression)
18
19 def publish_expression(self):
20 msg = Expression()
21 msg.valence = self.valence
22 msg.arousal = self.arousal
23
24 self.valence += self.valence_delta
25 self.arousal += self.arousal_delta
26
27 if self.valence > 1:
28 self.valence = 1.
29 self.valence_delta = 0.
30 self.arousal_delta = 0.05
31 if self.arousal > 1:
32 self.arousal = 1.
33 self.valence_delta = -0.05
34 self.arousal_delta = 0.0
35 if self.valence < -1:
36 self.valence = -1.
37 self.valence_delta = 0.0
38 self.arousal_delta = -0.05
39 if self.arousal < -1:
40 self.arousal = -1.
41 self.valence_delta = 0.05
42 self.arousal_delta = 0.0
43
44 rclpy.logging.get_logger('cycle_valence_arousal').info(
45 'valence=%f, arousal=%f' % (msg.valence, msg.arousal))
46
47 self.publisher_.publish(msg)
48
49
50if __name__ == '__main__':
51 rclpy.init()
52 node = CycleValenceArousal()
53 rclpy.spin(node)
54 rclpy.shutdown()
List of expressions#
The hri_msgs/Expression ROS message lists all pre-defined expression. The table below shows how these expressions are rendered on PAL robots.
Background and overlays#
Caution
As of PAL OS 24.9, changing the eyesβ background or applying overlays has not yet been ported from ROS 1 to ROS 2. This feature will be brought back in future releases.
See also#
attention-management
expressive_api