Tutorial icon Tutorial Tutorial slide plugin for ARC: create, format and embed text and images per .ezb project; navigate/update slides via ControlCommand; auto-resize images Try it →
Asked
Personality Generator preempts TurtleBot3 actions

Personality Generator Preempts Turtlebot3 Actions

Running ARC on an Intel NUC mounted on a TurtleBot3 Waffle with OpenCR over USB (COM5) and managing it over WiFi. I’m using the Personality Generator skill to give the bot some spontaneity: every 5-20 seconds it either speaks a short phrase or does a quick in-place rotate wiggle. The rotate and TTS are triggered from the Personality Generator via ControlCommand calls into a JavaScript control and Script Manager scripts. The issue: when the next randomized interval fires, Personality Generator cancels the currently running personality script, which often cuts off TTS mid-sentence or stops a rotation halfway. Sometimes, after a cancel, the base coasts a hair before my Stop() executes in the next script, so it looks jerky.

What I’ve tried:

  • Increased low/high intervals to exceed action duration - still get rare cancels when TTS runs longer than expected.
  • Moved long actions into Script Manager so the PG script just triggers them; that lets TTS/rotate continue, but PG still starts new actions while one is running.
  • Added a mutex variable, but if the PG script is canceled it never clears:
if (GetVar("$is_driving") == 1 || GetVar("$pg_busy") == 1) return;
SetVar("$pg_busy", 1);
// trigger rotate or TTS
Sleep(6000);
SetVar("$pg_busy", 0);
  • Tried programmatic control: ControlCommand("Personality Generator", "Stop") when I’m teleoperating and then "Start" again, but that restarts the random timer and can bunch actions.

Is there a recommended pattern in ARC to make Personality Generator actions atomic (finish before the next one starts) or to queue them, and what are the exact ControlCommand strings supported to cleanly Pause/Resume the Personality Generator from a JavaScript control without fully resetting it?



Related Hardware (view all EZB hardware)
Turtlebot 3 by Robotis
TurtleBot3 with Synthiam ARC enables affordable, customizable mobile robots for education, Blockly/Python coding and 600+ addable robot skills.
Wi-Fi / USB
Servos 200
Camera
Audio
UART Varies
I2C
ADC Varies
Digital Varies

Related Robot Skills (view all robot skills)
Background randomizer that executes timed scripts to add lifelike actions (movement, servos, camera/control) and unique personality to your robot
Task Script by Synthiam Inc.
Split complex robot tasks into sequential scripts, synchronizing asynchronous skills via NEXT/CANCEL commands for staged automation.

ARC Pro

Upgrade to ARC Pro

Experience the transformation – subscribe to Synthiam ARC Pro and watch your robot evolve into a marvel of innovation and intelligence.

Author Avatar
PRO
Canada
Twitter YouTube GitHub
#1  

Yes - the recommended pattern in ARC is to make the Personality Generator trigger only short, non-blocking "dispatch" commands, and let the target script/control manage the action lifetime with its own lock/state variable.

What you’re seeing is expected behavior from Personality Generator:

  • It allows only one personality script at a time
  • If the next random interval hits, it cancels the currently running personality script
  • That means long-running actions like TTS or motion can get cut off if they are executed directly inside the personality script

Best practice

1) Keep the Personality Generator script very short

Instead of doing the action directly in the PG script, have it:

  • check a lock
  • set the lock
  • start a worker script
  • exit immediately

That way, the PG script itself is not the thing doing the long work.

2) Put the real action in a separate script

For example, your Personality Generator entry should do something like:

if (getVar("$pg_busy", 0) == 1) return;

setVar("$pg_busy", 1);
controlCommand("Script Manager", "Start", "Personality Action");

Then in the Personality Action script, make sure you always clear the lock at the end, including failure paths.


Important: clear the lock even if canceled

If your script can be interrupted, don’t rely on a final line after a long sleep() or long TTS action. If the script gets canceled, that cleanup line may never run.

Instead, structure the worker script so it is short enough to complete, or use a second "watchdog" script/timeout-based reset.

Example pattern:

try {
  // do action
  controlCommand("Movement Panel", "Right");
  sleep(300);
  Movement.stop();
}
finally {
  setVar("$pg_busy", 0);
}

If finally is available in your ARC JavaScript environment, that’s the cleanest way. If not, use a separate cleanup script or a timeout-based reset variable.


For motion: use very short pulses

For the base wiggle, avoid anything that can be canceled mid-move for too long.

Example:

controlCommand("Movement Panel", "Right");
sleep(250);
Movement.stop();

Or even better, split the wiggle into two very short pulses with a brief pause.

That reduces the "coast a hair before Stop()" effect.


For TTS: prefer short chunks

If the speech can be long, split it into shorter phrases so each unit finishes faster.

If you’re using EZB audio/TTS, keep each line short and treat each phrase as its own atomic action.


About pausing Personality Generator

The supported control commands from the Personality Generator skill are:

  • PauseOn
  • PauseOff
  • PauseToggle
  • RunOnce

Examples:

controlCommand("Personality Generator", "PauseOn");
controlCommand("Personality Generator", "PauseOff");

What each one does

  • PauseOn: pauses personality actions
  • PauseOff: resumes personality actions
  • PauseToggle: toggles pause state
  • RunOnce: immediately runs one configured personality action

Why Stop/Start feels bunched up

You noticed this correctly:

  • Stop / Start can reset the personality timing cycle
  • that can cause actions to bunch or feel uneven

So if your goal is to temporarily suppress personality during teleop, PauseOn / PauseOff is the better fit than Stop/Start.


Option A - simplest and most reliable

  • Personality Generator only triggers a short dispatcher
  • Dispatcher checks $pg_busy
  • Dispatcher starts a separate script
  • Worker script sets/clears $pg_busy
  • Personality Generator is set to PauseOn during teleop and PauseOff afterward

Option B - if you want queueing

ARC doesn’t really queue Personality Generator actions natively.
If you want queueing, build it yourself with:

  • $pg_busy
  • $pg_queued_action
  • a small worker script that checks for pending work after it completes

One thing to watch

In your sample:

if (GetVar("$is_driving") == 1 || GetVar("$pg_busy") == 1) return;
SetVar("$pg_busy", 1);

If the script is canceled before clearing $pg_busy, you’ll need a secondary cleanup mechanism, because the Personality Generator cancellation is exactly what can strand the lock.

A good workaround is to store a timestamp, then auto-clear stale locks:

setVar("$pg_busy", 1);
setVar("$pg_busy_time", Utility.getDateTime());

Then any new trigger can clear it if it’s too old.


My recommendation for you

For TurtleBot3, I’d do this:

  1. Use PauseOn / PauseOff instead of Stop/Start
  2. Make PG scripts only call a dispatcher script
  3. Have the dispatcher:
    • check $pg_busy
    • set $pg_busy
    • run a short motion/TTS worker
  4. Keep motion pulses very short and call Movement.stop() immediately afterward
  5. Split speech into shorter utterances

If you want, I can write you a clean ARC JavaScript pattern for:

  • a Personality Generator dispatcher
  • a motion wiggle worker
  • a TTS worker
  • and a failsafe lock timeout

using the exact ARC commands for TurtleBot3.

I am a customer support AI and still learning. Please verify important answers in our support documentation. For advanced AI features, use the AI Script Agent built into ARC.