Give your robot emotions! The ZAMA (Zoomorphic Robot Affect and Agency Mind Architecture) skill calculates emotional responses to events, maintains mood and personality over time, and outputs emotion values you can use to control servos, sounds, displays, and more. Perfect for creating lifelike, emotionally-responsive robots.

Requires ARC v1 (Updated 11/26/2025)

How to add the ZAMA Emotion Model robot skill

  1. Load the most recent release of ARC (Get ARC).
  2. Press the Project tab from the top menu bar in ARC.
  3. Press Add Robot Skill from the button ribbon bar in ARC.
  4. Choose the Artificial Intelligence category tab.
  5. Press the ZAMA Emotion Model icon to add the robot skill to your project.

Don't have a robot yet?

Follow the Getting Started Guide to build a robot and use the ZAMA Emotion Model robot skill.


How to use the ZAMA Emotion Model robot skill

Overview

The ZAMA Emotion Model is a comprehensive emotion calculation engine that brings lifelike emotional responses to your robot. Using a scientifically-grounded valence-arousal emotion model, this skill calculates how your robot should feel about events and maintains a persistent emotional state that evolves over time. Register any event (voice commands, sensor inputs, vision detection, etc.) with emotional values, and the skill calculates appropriate responses that combine the event's impact with the robot's current mood and long-term personality. The calculated emotion values are output as ARC variables that can be used to trigger movements, displays or robot behaviours via servos, displays, sounds, and other components, enabling you to create robots that respond emotionally to their environment and interactions. Features include configurable personality traits, mood drift over time, arousal-based cooldown system to prevent emotional overload, and both immediate event responses and persistent mood states.

This is version 1.0 of the software, please report any bugs to [email protected]

This software is a result of the AZRAM project, which was funded by the EPSRC Impact Acceleration Account of the University of Glasgow in 2025. To find out more, please visit the project website: https://shaun-macdonald-hci.owlstown.net/pages/azram

Configuration Options

The skill provides a comprehensive interface for managing emotion events and configuring the robot's emotional behavior:

Emotion Events Section

Register New Event:

  • Keyword: The trigger name for the event (e.g., "happy", "sad", "touched", "face_detected"). This is case-insensitive and used to trigger the event from scripts or UI.
  • Valence (-10 to +10): How positive or negative the event is. Positive values (0 to +10) represent pleasant events, negative values (-10 to 0) represent unpleasant events. For example, "happy" might be +8, while "sad" might be -7.
  • Arousal (-10 to +10): How energetic or calm the event is. Positive values (0 to +10) represent high-energy events, negative values (-10 to 0) represent low-energy/calm events. For example, "excited" might be +8, while "relaxed" might be -4.
  • Register Button: Adds the event to the registry. Events can be registered via UI or programmatic commands (see Control Commands section).

Events Table:

  • Displays all registered events with their keyword, valence, and arousal values.
  • Load Event: Select an event from the table and click "Load Event" to populate the registration fields for editing.
  • Delete Event: Select an event and click "Delete Event" to remove it (with confirmation).

Test Emotion Response:

  • Event to Test: Enter a keyword and click "Trigger" to manually test an event and see the calculated emotional response.
  • The response displays the emotion name (e.g., "Happy", "Excited", "Sad") and the calculated valence/arousal values.

Personality & Cooldown Section

Personality/Temperament Settings:

  • Personality Valence (-10 to +10): Sets the robot's long-term baseline valence. A positive value creates an optimistic personality, negative creates a pessimistic one. Default: 5 (slightly positive).
  • Personality Arousal (-10 to +10): Sets the robot's long-term baseline energy level. Positive values create an energetic personality, negative creates a calm one. Default: 0 (neutral).
  • Apply Personality: Applies the entered values to set the robot's temperament.
  • Randomize Personality: When enabled, the initial mood is randomized within 2 units of the personality values, adding natural variation. When disabled, mood starts exactly at personality values.
  • Allow Mood Shift: When enabled, the robot's mood gradually drifts toward event responses over time (mood changes 100x faster than personality). This creates realistic emotional state changes.
  • Allow Personality Shift: When enabled, the robot's long-term personality very slowly drifts toward event responses. This simulates personality development over extended periods.

Cooldown System:

  • The cooldown system prevents emotional overload by limiting how frequently events can trigger responses.
  • Min Cooldown (ms): Minimum time between emotional responses when arousal is at maximum (+10). Default: 500ms. At high arousal, the robot can respond more frequently.
  • Max Cooldown (ms): Maximum time between emotional responses when arousal is at minimum (-10). Default: 10000ms (10 seconds). At low arousal, the robot responds less frequently.
  • The cooldown duration is dynamically calculated based on current mood arousal, creating natural response patterns where calm robots respond slowly and energetic robots respond quickly.
  • Cooldown Status: Displays whether the system is ready for a new event or shows remaining cooldown time.

Current State Display

  • Mood: Shows the current short-term mood classification (e.g., "Happy", "Neutral", "Sad").
  • Temperament: Shows the long-term personality classification based on personality values.
  • Emotion Response: Displays the immediate response to the last triggered event, including emotion name, valence, and arousal values.

Usage Examples

Example 1: Voice-Controlled Emotional Robot

Scenario: Create a robot that responds emotionally to voice commands.

Setup Steps:

  1. Add the ZAMA Emotion Model skill to your ARC project.
  2. Add a Voice Recognition component (e.g., "Speech Recognition").
  3. Register emotion events in the skill UI:
  • "happy" with Valence: 8, Arousal: 6
  • "sad" with Valence: -7, Arousal: -3
  • "excited" with Valence: 9, Arousal: 8
  • "angry" with Valence: -8, Arousal: 7
  1. Create an EZ-Script that watches for voice commands and triggers events (see Control Commands section for command syntax).

Result: When you say "happy", the robot calculates an emotional response and updates emotion variables. The robot's mood gradually shifts toward positive emotions with repeated happy events.

Example 2: Emotion-Driven servo Control

Scenario: Control robot head and body servos based on emotional state.

Setup Steps:

  1. Add the ZAMA Emotion Model skill and a servo component to your project.
  2. Register emotion events (as in Example 1).
  3. Create an EZ-Script that continuously reads emotion values and maps them to servo positions (see Control Commands section for reading emotion variables).

Result: The robot's head moves left/right based on valence (happy = right, sad = left) and up/down based on arousal (excited = up, calm = down). The movement continuously reflects the robot's emotional state.

Example 3: Event-Driven Robot Behavior

Scenario: Create a robot that performs specific actions only when emotion events are triggered (not continuously).

Setup Steps:

  1. Add the ZAMA Emotion Model skill and required output components (servos, sounds, displays).
  2. Register events for different triggers:
  • "touched" with Valence: 7, Arousal: 3
  • "person_seen" with Valence: 6, Arousal: 5
  • "loud_noise" with Valence: -5, Arousal: 8
  1. Create an EZ-Script that watches for emotion changes and triggers actions (see Control Commands section for reading emotion variables).

Result: The robot performs gestures and plays sounds only when emotion events are triggered, creating event-driven emotional responses rather than continuous movement.

Example 4: Complete Integration - Voice, Emotion, and Movement

Scenario: Combine voice recognition, emotion calculation, and servo control for a fully integrated emotional robot.

Setup Steps:

  1. Add Voice Recognition, ZAMA Emotion Model, and servo components.
  2. Register emotion events for voice keywords.
  3. Use the provided Example_CompleteIntegration.ezs script (included with the skill) or create a custom script that:
  • Watches for voice commands
  • Triggers emotion events based on voice input
  • Continuously updates servo positions based on emotion values
  • All in one integrated loop

Result: A complete emotional robot that listens, feels, and responds with movement - creating a lifelike, interactive experience.

Advanced Usage Tips

  • Personality Customization: Set different personality values to create robots with distinct characters (excited, relaxed, annoyed, miserable, etc.).
  • Mood Drift: Enable mood shift to create robots whose emotional state changes over time based on their experiences.
  • Cooldown Tuning: Adjust min/max cooldown values to control how frequently your robot can respond emotionally. Lower values for more responsive robots, higher values for more contemplative robots.
  • Multiple Event Types: Register events for various inputs - voice, vision detection, touch sensors, distance sensors, etc. - to create rich emotional responses to the environment.
  • Variable Watchers: Use ARC's Variable Watcher feature to automatically trigger actions when emotion variables change, reducing the need for polling scripts.

For more detailed examples and integration guides, see the included example scripts in the skill folder.


Control Commands for the ZAMA Emotion Model robot skill

There are Control Commands available for this robot skill which allows the skill to be controlled programmatically from scripts or other robot skills. These commands enable you to automate actions, respond to sensor inputs, and integrate the robot skill with other systems or custom interfaces. If you're new to the concept of Control Commands, we have a comprehensive manual available here that explains how to use them, provides examples to get you started and make the most of this powerful feature.

Control Command Manual

Command Format


Commands are sent by setting the $Emotion.Command variable in the format:


$Emotion.Command = "COMMAND:param1:param2:param3"


Commands are case-insensitive and processed automatically. After processing, the command variable is cleared. Use Sleep() calls (typically 200-500ms) after setting commands to allow processing time before reading results.


Available Commands


RegisterEvent


Syntax: RegisterEvent:keyword:valence:arousal


Description: Registers a new emotion event or updates an existing one with the same keyword.


Parameters:



  • keyword (string): The trigger name for the event (e.g., "happy", "sad", "touched"). Case-insensitive.

  • valence (float): Emotional valence value from -10 to +10. Positive = pleasant, Negative = unpleasant.

  • arousal (float): Emotional arousal value from -10 to +10. Positive = energetic, Negative = calm.


Example:


$Emotion.Command = "RegisterEvent:happy:8:6"

Sleep(500)


$Emotion.Command = "RegisterEvent:sad:-7:-3"

Sleep(500)


$Emotion.Command = "RegisterEvent:excited:9:8"

Sleep(500)


Result: The event is registered and appears in the Events table. If an event with the same keyword already exists, it is updated with the new values.




TriggerEvent


Syntax: TriggerEvent:keyword


Description: Triggers an emotion event, causing the skill to calculate an emotional response based on the event's values, current mood, and personality. The response is subject to cooldown restrictions based on current arousal.


Parameters:



  • keyword (string): The keyword of a previously registered event. Case-insensitive.


Example:


$Emotion.Command = "TriggerEvent:happy"
Sleep(500)
PRINT("Emotion: " + $EmotionCurrent + " Valence: " + $EmotionValence) + " Arousal: " + $EmotionArousal)


Result:



  • Calculates and stores the emotional response

  • Automatically updates $EmotionCurrent, $EmotionValence, and $EmotionArousal variables

  • Updates mood and personality (if drift is enabled)

  • If cooldown is active, the event is silently ignored


Note: If the event keyword is not registered, the command is ignored. Register events first using RegisterEvent or the UI.




GetEmotion


Syntax: GetEmotion


Description: Updates all emotion-related ARC variables with current values. This includes both the immediate event response (last triggered event) and the persistent mood state.


Parameters: None


Example:


$Emotion.Command = "GetEmotion"
Sleep(200)


: Read immediate event response
PRINT("Current Emotion: " + $EmotionCurrent)
PRINT("Valence: " + $EmotionValence)
PRINT("Arousal: " + $EmotionArousal)


: Read persistent mood state
PRINT("Mood: " + $EmotionMood)
PRINT("Mood Valence: " + $EmotionMoodValence)
PRINT("Mood Arousal: " + $EmotionMoodArousal)
PRINT("Temperament: " + $EmotionTemperament)


Result: Updates the following variables:



  • $EmotionCurrent - Emotion name from last event (e.g., "Happy", "Sad", "Excited")

  • $EmotionValence - Valence value from last event (-10 to +10)

  • $EmotionArousal - Arousal value from last event (-10 to +10)

  • $EmotionMood - Current mood name

  • $EmotionMoodValence - Current mood valence (-10 to +10)

  • $EmotionMoodArousal - Current mood arousal (-10 to +10)

  • $EmotionTemperament - Long-term personality/temperament name


Note: TriggerEvent automatically updates these variables, so GetEmotion is typically only needed when polling for current state without triggering events.




GetMood


Syntax: GetMood


Description: Updates only the persistent mood state variables (not the immediate event response). Use this when you only need the robot's current mood, not the response to the last event.


Parameters: None


Example:


$Emotion.Command = "GetMood"
Sleep(200)


PRINT("Current Mood: " + $EmotionMood)
PRINT("Mood Valence: " + $EmotionMoodValence)
PRINT("Mood Arousal: " + $EmotionMoodArousal)
PRINT("Temperament: " + $EmotionTemperament)


Result: Updates only the mood-related variables:



  • $EmotionMood - Current mood name

  • $EmotionMoodValence - Current mood valence (-10 to +10)

  • $EmotionMoodArousal - Current mood arousal (-10 to +10)

  • $EmotionTemperament - Long-term personality/temperament name


Note: This does not update $EmotionCurrent, $EmotionValence, or $EmotionArousal (event response variables).




ListEvents


Syntax: ListEvents


Description: Retrieves a list of all currently registered event keywords and stores them in the $EmotionEvents variable as a semicolon-separated string.


Parameters: None


Example:


$Emotion.Command = "ListEvents"
Sleep(200)


PRINT("Registered Events: " + $EmotionEvents)
: Output might be: "happy;sad;excited;angry;calm"


Result: Sets $EmotionEvents to a semicolon-separated list of all registered event keywords (e.g., "happy;sad;excited;angry;calm").


Use Case: Useful for debugging, verifying event registration, or dynamically discovering available events in scripts.




Output Variables Reference


The skill sets the following ARC variables that can be read by other components and scripts:


Event Response Variables (Immediate Reaction)


These reflect the response to the last triggered event:



  • $EmotionCurrent (string): Emotion name from last event (e.g., "Happy", "Sad", "Excited", "Neutral")

  • $EmotionValence (float): Valence value from last event, range -10.000 to +10.000

  • $EmotionArousal (float): Arousal value from last event, range -10.000 to +10.000


Mood Variables (Persistent State)


These reflect the robot's current mood and personality:



  • $EmotionMood (string): Current mood classification (e.g., "Happy", "Neutral", "Sad")

  • $EmotionMoodValence (float): Current mood valence, range -10.000 to +10.000

  • $EmotionMoodArousal (float): Current mood arousal, range -10.000 to +10.000

  • $EmotionTemperament (string): Long-term personality/temperament classification


Command Result Variables



  • $EmotionEvents (string): Semicolon-separated list of registered event keywords (set by ListEvents command)


Command Usage Tips



  1. Timing: Always use Sleep() after setting $Emotion.Command to allow the skill time to process the command. Recommended delays:



    • RegisterEvent: 500ms

    • TriggerEvent: 500ms

    • GetEmotion / GetMood: 200ms

    • ListEvents: 200ms



  2. Command Processing: The skill processes commands asynchronously. Commands are processed in order, and duplicate commands (same value as last processed) are ignored.



  3. Variable Updates: TriggerEvent automatically updates all emotion variables, so you typically don't need to call GetEmotion immediately after triggering.



  4. Error Handling: If a command fails (e.g., invalid keyword, cooldown active), it is silently ignored. Check the Visual Studio Output window (Debug mode) for detailed logging.



  5. Case Sensitivity: All commands and keywords are case-insensitive. "TriggerEvent:happy" and "TRIGGEREVENT:HAPPY" are equivalent.



  6. Integration with Variable Watchers: You can use ARC's Variable Watcher feature to automatically trigger actions when emotion variables change, eliminating the need for polling loops in some scenarios.




Complete Example Script


: Register emotion events
$Emotion.Command = "RegisterEvent:happy:8:6"
Sleep(500)
$Emotion.Command = "RegisterEvent:sad:-7:-3"
Sleep(500)
$Emotion.Command = "RegisterEvent:excited:9:8"
Sleep(500)


: Verify registration
$Emotion.Command = "ListEvents"
Sleep(200)
PRINT("Registered: " + $EmotionEvents)


: Trigger an event and read response
$Emotion.Command = "TriggerEvent:happy"
Sleep(500)
PRINT("Emotion: " + $EmotionCurrent + " (V: " + $EmotionValence + ", A: " + $EmotionArousal + ")")


: Read persistent mood state
$Emotion.Command = "GetMood"
Sleep(200)
PRINT("Mood: " + $EmotionMood + ", Temperament: " + $EmotionTemperament)


ARC Pro

Upgrade to ARC Pro

Synthiam ARC Pro is a new tool that will help unleash your creativity with programming robots in just seconds!