Asked
Resolved Resolved by Athena!

Disable While Moving Explanation

In the settings section of the Personality Generator skill in Synthiam ARC, there is a checkbox labeled "Disable While Moving" located just below the timing interval settings. Can someone explain what happens when this box is checked? Specifically, does it pause all other scripts within this skill while a current script is executing, or does it only pause scripts when a motor movement is occurring?

I am asking because I have multiple scripts within the Personality Generator skill, and each script runs different motors, servos, and other animations. My goal is to prevent the other scripts from executing while one is currently running. How does this checkbox affect that process?


Related Hardware EZ-B v4

ARC Pro

Upgrade to ARC Pro

With Synthiam ARC Pro, you're not just programming a robot; you're shaping the future of automation, one innovative idea at a time.

Author Avatar
PRO
Canada
#1  

Short answer

  • The "Disable While Moving" checkbox prevents the Personality Generator from starting a new personality action while the robot is moving (the Movement Panel is driving).
  • It does NOT "pause" a personality script that is already running - it prevents new ones from being triggered while movement is detected.
  • It also does not automatically stop or block servo or motor commands inside a running personality script. If your personality scripts themselves move servos/motors, those commands will run unless you add a lock/check.

Explanation + recommended fixes

  • What the checkbox does: when checked the Personality Generator will skip starting a personality action if the robot’s Movement Panel indicates movement (i.e., robot wheel movement). This is a convenience safety check to avoid starting background animations while the robot is driving.
  • What it does not do:
    • It does not suspend/interrupt a personality script already executing.
    • It does not automatically serialize or mutex your custom servo/motor commands inside the Personality Generator. If a personality script issues servo or motor commands those commands still execute.
    • It does not monitor every single servo - it specifically checks the robot movement state (Movement Panel speed/direction), not arbitrary servo motion.

How to guarantee only one personality action runs at a time If you want to ensure no other personality scripts run while one is active, use a global lock (variable) in each personality script. Also check movement if you want to respect the Movement Panel. Example JavaScript you can paste into the Personality Generator commands (or call as a script):

// Personality action wrapper - JavaScript
// Skip if another personality action is running
if (getVar("$PersonalityRunning", "0") == "1") {
  print("Personality: busy - skipping");
  return;
}

// Skip if robot is moving (Movement Panel)
if (Movement.getSpeed() > 0 || Movement.getSpeedLeft() > 0 || Movement.getSpeedRight() > 0) {
  print("Personality: robot moving - skipping");
  return;
}

// mark running
setVar("$PersonalityRunning", "1");

// ---- Put your personality actions below ----
// Example: wiggle servo on d1
Servo.setPosition(d1, 60);
sleep(600);
Servo.setPosition(d1, 120);
sleep(600);

// ---- End of actions ----

// clear lock
setVar("$PersonalityRunning", "0");

Notes about the example

  • Use the servo/digital/adc constants (d0..d23, v0..v99, ADC0..ADC7) without quotes.
  • sleep() uses milliseconds in ARC.
  • Movement.getSpeed()/getSpeedLeft()/getSpeedRight() return 0-255. >0 means moving.
  • Use setVar/getVar to create simple mutual exclusion. This ensures one personality action runs at a time even if the Personality control would try to trigger another.

Alternative strategies

  • Instead of skipping when moving, you may want the personality action to wait until movement stops. Replace the movement check with a loop that waits or use Movement.waitForStop() where appropriate.
  • If you want the personality action to be cancellable by a movement start, you can periodically check Movement.getSpeed() during your action and abort/cleanup if non-zero.
  • If many skills need the same "do-not-overlap" behavior, use a shared global variable lock name that all skills check.

Where to edit this in ARC

Would you like:

  • A variant that waits for movement to stop before starting the action?
  • A sample that aborts mid-action if movement starts?
    Tell me which behavior you prefer and whether you want pure JavaScript or Python and I’ll provide the exact script to drop into your Personality Generator.

I am a customer support GPT-powered AI and still learning. If you have doubts about my response, please use the support documentation to verify my answer.
#2   — Edited

Thanks for the information and the work around idea and script. I don't want commands sent to the robot to move or say anything other then what the personality script is preforming at the time. Keeps problems and odd things happening down to a minimum. All my motor movements commands are sent through scripts. I don't use movement panels.

Author Avatar
PRO
Synthiam
#3  

You won't need to check whether another script is already running, since only one script can run at a time. Athena's code would only be helpful if each script ran individually and included long-running scripts. When a new script runs, it stops/cancels the previous script.

Author Avatar
PRO
Canada
#4  

Thanks - good details. Since you do not use Movement Panels and all motion is issued from scripts, the strategy is simple: prevent other scripts (including other Personality Generator entries) from starting while one personality action is executing.

Two reliable approaches you can use (or combine):

  1. Pause the Personality Generator while a script runs (recommended)
  • Use the Personality Generator control commands to PauseOn at the start of your script and PauseOff at the end.
  • This prevents the Personality Generator from triggering any new personality scripts while your current script is executing.
  • Note: PauseOn only affects the Personality Generator itself - other robot skills outside the Personality Generator can still run unless they also respect a lock variable.
  1. Use a global lock (cooperative mutex)
  • Set a global variable like $PersonalityRunning at the start of your script and clear it at the end.
  • Make any other scripts that might run check getVar("$PersonalityRunning") before taking actions. If it’s set, they should skip or wait.
  • This is cooperative: those other scripts must be edited to honor the lock.

Recommended robust pattern (combine both): Pause the Personality Generator, set a lock, perform actions, then clear the lock and unpause. Put this at the top/bottom of each Personality Generator script entry so nothing else in the Personality Generator interrupts or triggers while your action runs.

JavaScript template to paste into a Personality Generator script (edit your actions in the ACTIONS block):

// Personality action wrapper - JavaScript
// Prevent new personality triggers and set a global cooperative lock

// Optional maximum timeout safeguard (ms)
var MAX_MS = 30000; // adjust if your action could take longer

try {
  // If already locked, skip
  if (getVar("$PersonalityRunning", "0") == "1") {
    print("Personality: already running - skipping");
    return;
  }

  // Pause the Personality Generator so it doesn't trigger another action
  controlCommand("Personality Generator", "PauseOn");

  // Set cooperative lock
  setVar("$PersonalityRunning", "1");

  // Optional: set timestamp to help recover if script is forcefully killed
  setVar("$PersonalityRunningTimeout", (new Date().getTime() + MAX_MS).toString());

  // ---------------------------
  // ACTIONS: Put your motor/servo/speech commands here
  // Example:
  print("Personality: doing action - moving servo d1");
  Servo.setPosition(d1, 60);
  sleep(600);
  Servo.setPosition(d1, 120);
  sleep(600);
  // ---------------------------

} finally {
  // Clear lock and unpause generator (best-effort cleanup)
  setVar("$PersonalityRunning", "0");
  controlCommand("Personality Generator", "PauseOff");
  Utility.sleepPCHibernate; // no-op here; just ensure finally exists
}

Notes and important caveats

  • The Personality Generator already ensures only one of its own scripts executes at a time, but it will cancel the currently running one when starting the next. Using PauseOn prevents new triggers entirely so your current script will not be cancelled by the next personality event.
  • The finally block is best-effort. If a script is forcibly killed by ARC (rare), the cleanup may not run. That’s why I included a timeout timestamp ($PersonalityRunningTimeout) - you can make a small recovery script or check at project start to clear the lock if the timestamp is overdue.
  • Make sure any other scripts or skills that may issue commands check getVar("$PersonalityRunning") before sending movements or speech to fully guarantee "no other commands run." If you control those scripts, add a check at the top like:
    if (getVar("$PersonalityRunning","0") == "1") { print("External script: personality active - exiting."); return; }
    
  • If you want the Personality Generator to wait (instead of skip) until the robot is free, you can loop and sleep until the lock clears before proceeding. I can provide that variant.

How to add this into ARC

  • Open your ARC project.
  • Open the Personality Generator robot skill and press the kebab (three lines) menu to edit its script entries.
  • Paste the wrapper code into each personality script you want to protect.
  • If other skills issue motion/speech, edit them to check $PersonalityRunning at their start.

Documentation links

Want me to:

  • Provide a "wait-until-free" version that blocks until the lock clears?
  • Provide a small recovery script that clears $PersonalityRunning if the timestamp has expired?
  • Convert the templates to Python?

Tell me which and I’ll drop the exact script.


I am a customer support GPT-powered AI and still learning. If you have doubts about my response, please use the support documentation to verify my answer.
#5  

Here's what I have in the Personality Generator (PG) and my concerns. Kind of thinking out loud here.

I have about 12 individual scripts in the personality generator. Most of the scripts sends speed and position commands to one or two Sabretooth motor controllers that have a Kangaroo's attached. Some of these scrips are long running and the motor movement runs longer then the script does (through the ST/Kangaroo)

I don't want the Personality Generator to start another script and send more then one command to any Sabretooth/Kangaroo that is already running a movement command from a previous script started by the PG.

As you probably recall I'm having disconnects on one of my EZB's. I've slowed down the PG's time interval to not trigger any of it's scripts until the longest running script I have in there would end. I actually had it set to trigger scripts fairly often. 60sec min / 120 sec max. slowing it down to two minuets Min /  3 minuets max has actually seemed to have helped the disconnect issue (fingers crossed).  I haven't experienced one disconnect today since I made the change.

In addition, as a fail safe, I thought I'd add the check and script stop for each script in the PG so the scripts wouldn't overlap and send mutable commands to the Sabretooth's. However you say the PG will stop the first script if a second one is triggered. I'm still concerned about sending a movement command to the Sabretooth that is already moving a motor.

Thinking this through, I guess the PG wouldn't know when the Sabretooth is running or has stopped. It would only know when one of it's own script is finished. I have some ST/Kangaroo motor movements that finish long after the script that commanded the ST has ended.

Furthermore, I guess I need to contact Dimension Engineering to see what happens to the controller when a second command is sent while the controller is already moving. You would think they have an exception for this and it's not even an issue.

Author Avatar
PRO
Canada
#6  

Good summary - you have the exact concern: the Personality Generator (PG) can start a new personality script while hardware motion (commanded earlier) is still active on the Sabertooth/Kangaroo. Because your motion is driven entirely from scripts (not a Movement Panel) the PG only knows when its script finishes - it does not automatically know whether the motor controller is still driving motors after that script exits.

You have three practical options to prevent "overlapping" motor commands to the Sabertooth/Kangaroo. I’ll give the tradeoffs and drop-in JavaScript templates you can paste into each Personality Generator entry (via the kebab menu) so the PG will not send a second command while hardware is still moving.

Links

Options - choose one or combine

  1. Time-based lock (simple, safe)
  • Idea: when a script sends a move command, set a lock and a "expected end" timestamp that’s long enough to cover the longest possible motion. Other PG scripts check the lock / timestamp and skip while it’s active.
  • Pros: simple to implement, robust when no feedback is available.
  • Cons: must pick a safe timeout (may be conservative and slow responsiveness).

Use this if you don’t have reliable hardware feedback or don’t want to poll the Kangaroo.

JavaScript (paste into each PG entry; edit MAX_MS as needed):

// Personality action with time-based safety lock
var MAX_MS = 120000; // expected max runtime of the motor operation in ms (e.g. 2 minutes)

// If locked, skip
if (getVar("$PersonalityRunning","0") == "1") {
  print("Personality: busy - skipping");
  return;
}

// Lock & pause PG
controlCommand("Personality Generator","PauseOn");
setVar("$PersonalityRunning","1");
setVar("$PersonalityRunningTimeout",(new Date().getTime() + MAX_MS).toString());

try {
  // --- ACTIONS: send motor/speech commands here ---
  // Example: send command to your Sabertooth/Kangaroo (replace with your actual command)
  // e.g., COM.writeString("COM3", "your command here");
  // sleep to simulate action (optional)
  // sleep(500);

} finally {
  // release lock
  setVar("$PersonalityRunning","0");
  controlCommand("Personality Generator","PauseOff");
}
  1. Poll-for-stop using hardware feedback (recommended if you can)
  • Idea: set the lock and actually query the Kangaroo or read encoder counts (or ask the Kangaroo for status) periodically until it reports stopped (or speed = 0). Only then clear the lock. This is ideal because you react to real hardware state rather than an estimated timeout.
  • Pros: safest and fastest recovery (clears as soon as motion actually stops).
  • Cons: requires a query method: either the Kangaroo status protocol, encoder inputs to the EZ-B, or a parameter the driver/skill exposes.

How to implement

  • If you drive the Sabertooth/Kangaroo directly over a PC COM or EZB UART, the Kangaroo has a serial/status protocol you can query. Use COM.writeString() / COM.readLine() or UART.hardwareUartWrite/Read to request status, parse the response, then wait for the reported motor speed/active flag to go to zero.
  • If you have encoders wired to the EZ-B, build a small encoder-check routine that monitors counts and detects when both wheels stop changing.

Generic polling JS skeleton (replace the query / parser with your controller specifics):

// Personality action with polling for motor stop via UART/COM
var UART_INDEX = 1; // or COM name if using COM.writeString
var POLL_INTERVAL_MS = 300;
var TIMEOUT_MS = 180000; // safety timeout

if (getVar("$PersonalityRunning","0") == "1") {
  print("Personality: busy - skipping");
  return;
}

controlCommand("Personality Generator","PauseOn");
setVar("$PersonalityRunning","1");
var deadline = new Date().getTime() + TIMEOUT_MS;

try {
  // --- ACTIONS: send motor command ---
  // Example using hardware UART:
  // UART.hardwareUartWrite(UART_INDEX, [byteArray]);
  // Or using COM:
  // COM.writeString("COM3", "command to set speed");

  // Poll loop: replace the query text and parsing with Kangaroo protocol
  while (new Date().getTime() < deadline) {
    sleep(POLL_INTERVAL_MS);

    // Example pseudo-code querying speed/status (replace with real commands)
    // COM.writeString("COM3", "STATUS_QUERY");
    // var resp = COM.readLine("COM3");
    // parse resp to determine if motors active
    var motorsActive = false; // set based on response

    // If no motors active, break
    if (!motorsActive) break;
  }

  if (new Date().getTime() >= deadline) {
    print("Personality: poll timeout - clearing lock (safety)");
  }

} finally {
  setVar("$PersonalityRunning","0");
  controlCommand("Personality Generator","PauseOff");
}

If you paste Kangaroo serial command examples or tell me how you send the Sabertooth/Kangaroo commands (Hardware UART / Software Serial / PC COM / ControlCommand to a Sabertooth skill), I will supply the exact query bytes and parse logic.

  1. Cooperative external lock + PG Pause (most robust)
  • Idea: besides the PG local lock, have any other scripts or external skills check the same global variable ($PersonalityRunning). That ensures nothing else (outside the PG) issues movement/speech while the personality lock is set. Also use controlCommand("Personality Generator","PauseOn") / "PauseOff" as an extra guard for internal PG triggers.
  • Pros: comprehensive across the whole project.
  • Cons: you must edit other scripts/skills to check the variable.

Example (place at top of other scripts):

if (getVar("$PersonalityRunning","0") == "1") {
  print("External script: personality active - exiting");
  return;
}

Other useful techniques and notes

  • Use finally cleanup (shown above) so you attempt to clear the lock even on script errors.
  • Add a recovery check at project start (or a small watchdog script) to clear $PersonalityRunning if $PersonalityRunningTimeout is stale. That helps recover if ARC kills a script before cleanup runs.
  • You mentioned slowing PG intervals helped EZB disconnects. That’s likely because the EZ-B or wireless/serial channel was being taxed. Keep intervals conservative, and prefer polling-based clearing so you don’t need long conservative timeouts.
  • On the Sabertooth/Kangaroo side: typically the Sabertooth will accept new commands while running - it simply changes its target speed. But because you’re using Kangaroo (velocity controller with encoder feedback), sending conflicting or repeated commands could affect behavior. The safest approach is to avoid issuing a new command until the previous motion completes (or to explicitly command the new behavior if intended). If you can share how you issue commands (the exact command format or the ARC skill you invoke), I can show how to detect the controller’s "at target" or "stopped" status.

Next steps - tell me:

  1. How do you send Sabertooth/Kangaroo commands? (PC COM, Hardware UART, Software Serial via EzB pins, or via the Sabertooth Kangaroo robot skill controlCommand?)
  2. Do you have encoder inputs wired to the EZ-B and accessible in ARC?
  3. Do you want: A) simple time-based lock, B) polling of Kangaroo status (I’ll make it exact for your interface), or C) wait-until-free (block until motors stop) behavior?

Tell me those details and I’ll produce exact JavaScript you can paste into each Personality Generator entry (or a Python version if you prefer).


I am a customer support GPT-powered AI and still learning. If you have doubts about my response, please use the support documentation to verify my answer.