Advanced Speech Recognition icon Advanced Speech Recognition — Azure Cognitive Speech recognition for ARC with custom API credentials, scripting, language control, and text output for detected phrases Try it →
Asked
1 Participant
Utility.Getrandomunique Not Truly Unique

Utility.Getrandomunique Not Truly Unique

This question is about the ARC JavaScript command: Utility.getRandomUnique.

I know there are two Utility random functions: Utility.getRandom and Utility.getRandomUnique. The one I mentioned first, Utility.getRandomUnique, is supposed to return a random integer between min (inclusive) and max (exclusive). According to its JavaScript API support page, this function should never return the same integer twice. However, I'm currently using the "Unique" random function on a list of seven scripts that I want to be picked from and started, and I get the same script triggered back-to-back very often. Is this function broken in ARC? I've used that command many other times and haven't experienced this level of repeated list picks.

For context: this runs as an ARC JavaScript script in my ARC project and the main script watches ADC readings from several momentary buttons connected to an EZB. When the EZB detects a voltage change on any of the buttons, this script runs and starts other scripts (Robot Skills) and animations. The overall script works well, but this repeated-pick behavior from Utility.getRandomUnique is frustrating. I can post the entire script if needed.

Any info is welcome.

Below is the section of a larger script that uses Utility.getRandomUnique. I reformatted the code for readability but did not change variable names or logic:

//-----------------------------------------------------------------------------
// This section will pause the already running "Personality Generator" & "Weather Loop" scripts.
// Those called animation scripts will handle restarting the running "Personality Generator" & 
// "Weather Loop" scripts when complete. 
// This section will pause and then watch for the global Var "$anamationStatus" to change to 0. 
// 0 is set by the called animation scripts showing that they are complete. Var is set to 1 in this script
// ============================================================================
actions[3] = function() {
    controlCommand("Personality Generator", "PauseOn"); // called script will restart this function
    controlCommand("Weather Loop", "ScriptStop"); // called script will restart this function
    setVar("$anamationStatus", "1");
    sleep(2500); // Lets intro sound clip finish from CF3 sound system and set Var to register.
    var animationList = [
        "Attack",
        "Danger! Danger!",
        "It's Launch Plus 8 Hours",
        "Pledge of Allegience",
        "Sing it",
        "Threat",
        "Take a soil sample"
    ];
    // pick one random animation
    var randomIndex = Utility.getRandomUnique(0, animationList.length);
    var selectedAnimation = animationList[randomIndex];
    print("ADC3: starting random animation -> " + selectedAnimation);
    // Random selected animation
    controlCommand("Robot Anamations", "ScriptStart", selectedAnimation);
    print("ADC3: completed animation -> " + selectedAnimation);
 
    // Wait for the $anamationStatus Variable to change to 0. 0 = animation complete, 1 = animation running
    while (getVar("$anamationStatus") == 1) {
        sleep(100);
    }
};


Related Hardware (view all EZB hardware)
EZ-B V4 by EZ-Robot
EZ-B v4 with Synthiam ARCx controls servos, sensors, camera and audio over Wi-Fi or USB serial, no firmware needed.
Wi-Fi / USB
Servos 24
Camera
Audio
UART 3
I2C
ADC 8
Digital 24

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
Script by Synthiam
Multi-language ARC Script: build, run and debug Blockly, JavaScript, EZ-Script or Python with Intellisense, run/save/load and Roboscratch support

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!

Author Avatar
PRO
Canada
Twitter YouTube GitHub
#1  

Utility.getRandomUnique() is not a "shuffle a list and never repeat in the future" function. It only guarantees that it won’t return the same number as the last call from that utility’s internal state. That means:

  • If you call it once per trigger, it may still feel repetitive over time.
  • It is not a built-in "no back-to-back repeats from a list of scripts forever" selector.
  • If the internal state gets reset by script timing, reloading, or another script context, you can absolutely see repeats.

So: it’s not broken - it’s just being used for a job it wasn’t designed to solve.

The better ARC approach

For a list of 7 actions, the proven method is:

  1. Pick a random index with Utility.getRandom()
  2. If it matches the previous index, pick again or shift it
  3. Store the last index in a global variable

That gives you true no-back-to-back repeats for your list, which is what you actually want.

var animationList = [
  "Attack",
  "Danger! Danger!",
  "It's Launch Plus 8 Hours",
  "Pledge of Allegience",
  "Sing it",
  "Threat",
  "Take a soil sample"
];

var lastIndex = parseInt(getVar("$lastAnimationIndex", "-1"));
var randomIndex = Utility.getRandom(0, animationList.length);

// prevent back-to-back repeat
if (animationList.length > 1 && randomIndex == lastIndex) {
  randomIndex = (randomIndex + 1) % animationList.length;
}

setVar("$lastAnimationIndex", randomIndex.toString());

var selectedAnimation = animationList[randomIndex];
print("ADC3: starting random animation -> " + selectedAnimation);

controlCommand("Robot Anamations", "ScriptStart", selectedAnimation);

Why this is better

  • Utility.getRandomUnique() is intended for generating a random integer that differs from the last returned value, not for maintaining a no-repeat playlist.
  • Your code is choosing from a static array, so the cleanest solution is to manage the last selection yourself.
  • This also makes the behavior predictable and easier to debug in ARC.

One thing I noticed in your script

You have:

setVar("$anamationStatus", "1");

and later:

while (getVar("$anamationStatus") == 1)

That variable name is spelled anamation, not animation. If that’s not intentional, it could create confusion later. Also, compare it consistently as a string or number. In ARC JavaScript, I’d keep it consistent:

while (getVar("$anamationStatus") == "1") {
  sleep(100);
}

If you want zero repeats until the whole list is exhausted

That’s a different behavior: a shuffle bag approach. ARC can do that too, and it’s a better fit if you want all 7 scripts to play once before any repeat happens. If that’s your real goal, I can show you a clean ARC JavaScript version using a shuffled array.

Quick question

Are you trying to avoid only back-to-back repeats, or do you want every animation to play once before any repeat happens?

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.