Variable State Saver icon Variable State Saver Persist and auto-load specified global variables between ARC sessions for consistent, personalized robot behavior and quick state restoration. Try it →
Asked
Six hexapod ultrasonic avoidance blocking

Six Hexapod Ultrasonic Avoidance Blocking

Running a Six Hexapod (EZ-B v4 over WiFi) with an HCSR04 mounted front-center (Trig=D0, Echo=D1) and ARC on Windows. Locomotion is via Auto Position Movement Panel using the stock Six gait actions (Walk Forward, Walk Backward, TurnRight, Stop). I added the Ultrasonic Collision Script skill with Detection Interval=100 ms, Minimum Distance=25 cm, and "Only trigger when moving forward" checked. The goal is simple: stop, back up, turn, then continue.

Two issues I can’t nail down:

  1. With "Only trigger when moving forward" ON, the collision script never fires during Auto Position forward walking, but it does fire if I uncheck that option. Does Ultrasonic Collision Script only recognize certain Movement Panels, or should Auto Position Movement Panel set the forward state that this skill expects?

  2. Because the skill pauses detection while the script runs, I get a few seconds of "blind" motion during the back-up/turn. Here’s my current script in the skill:

ControlCommand("Auto Position", "Action", "Stop")
sleep(250)
ControlCommand("Auto Position", "Action", "Walk Backward")
sleep(1500)
ControlCommand("Auto Position", "Action", "TurnRight")
sleep(1200)
ControlCommand("Auto Position", "Action", "Stop")

It works, but detection doesn’t resume until the last Stop completes, so it can miss a closer obstacle during the turn. I tried delegating to Script Manager to make it "non-blocking" like this:

if ($avoidance = 0)
  $avoidance = 1
  ControlCommand("Script Manager", "Start", "Avoidance")
endif

and then clearing $avoidance at the end of the Avoidance script, but the collision skill still seems to wait before it will retrigger. What’s the recommended pattern to integrate Ultrasonic Collision Script with Auto Position on Six so it only triggers while actually moving forward and avoids blocking detection during the avoidance maneuver?



Related Hardware (view all EZB hardware)
Six Hexapod by EZ-Robot
Six hexapod robot kit: Canadian-designed, customizable WiFi 6-legged platform with 12 servos/12 DOF for dynamic motion. Available at EZ-Robot.
Wi-Fi / USB
Servos 24
Camera
Audio
UART 3
I2C
ADC 8
Digital 24

Related Robot Skills (view all robot skills)
Create servo frames and actions to animate gaits and gestures with automatic motion planning, software ramping, movement panel, import/export
Ultrasonic sensor triggers custom script on object detection; configurable interval & min distance, with optional forward-only trigger for navigation.

ARC Pro

Upgrade to ARC Pro

Unlock the true power of automation and robotics by becoming a proud subscriber of Synthiam ARC Pro.

Author Avatar
PRO
Canada
Twitter YouTube GitHub
#1  

Yes - the behavior you’re seeing is expected, and it comes down to how the Ultrasonic Collision Script skill decides "moving forward" and how it pauses while its trigger script is running.

1) "Only trigger when moving forward" and Auto Position

The Ultrasonic Collision Script "movement check" is designed around ARC’s Movement Panel state. In practice, it works best when the robot is moving with a skill that updates the global movement direction/state used by ARC movement.

With Auto Position (Movement Panel), it should be able to participate in movement control, but the collision skill may not always recognize the forward state the way you expect, especially if the gait is being started through an action command rather than a direct movement command.

What to verify

  • Make sure you’re using the Auto Position (Movement Panel) version, not the non-movement version.
  • Confirm the skill title is exactly the one your scripts reference.
  • Test whether ARC’s movement state changes when the gait runs.

A good quick test is to add a tiny script temporarily:

print(getVar("$Direction"));

Run your forward gait and see if $Direction becomes the forward state you expect. If it does not, then the ultrasonic skill’s "only when moving forward" filter won’t see it.

Practical recommendation

For Six, the most reliable pattern is usually:

  • Let Auto Position handle the gait
  • Use the ultrasonic skill without the "only when moving forward" checkbox
  • Put the "am I moving forward?" logic in your script instead

That gives you full control and avoids relying on movement-state detection that may not line up perfectly with Auto Position transitions.


2) Why detection pauses during the script

That part is built into the skill:

when the obstacle is detected, the entered script runs, and the skill does not resume detection until that script completes

So even if you move the script into Script Manager, the collision skill still considers the trigger "active" until the original script finishes. In other words, starting another script doesn’t make the collision skill non-blocking.


Instead of relying on the collision skill to do the whole avoidance sequence, use it only as a trigger, then immediately hand off to a script that manages its own loop and re-checks distance during the maneuver.

Better approach

  1. Collision skill triggers.
  2. Script sets a global flag like $avoidance = 1.
  3. Script immediately stops walking.
  4. During reverse/turn, the script repeatedly checks the sensor.
  5. If the path clears, it exits early.
  6. Clear the flag when done.

That way, you’re not "blind" for the full 1.5-2 seconds.

Example pattern in JavaScript

I’d recommend using JavaScript rather than EZ-Script in ARC.

if (getVar("$avoidance", "0") == "1") {
  halt()
}

setVar("$avoidance", "1")
Movement.stop()
sleep(200)

// back up while checking distance
Movement.reverse(80)
var start = getTime()
while (true) {
  var distance = Ping.get(d0, d1)

  if (distance > 30) {
    break
  }

  if ((getTime() - start) > 1500) {
    break
  }

  sleep(100)
}

Movement.stop()
sleep(100)

// turn while checking distance
Movement.right(80)
start = getTime()
while (true) {
  var distance = Ping.get(d0, d1)

  if (distance > 30) {
    break
  }

  if ((getTime() - start) > 1200) {
    break
  }

  sleep(100)
}

Movement.stop()
setVar("$avoidance", "0")

Why this works better

  • You re-check distance during backup and turn
  • You don’t wait for a fixed blind pause
  • You can break out early if the obstacle clears
  • You keep the logic in one place

Even better: bypass the collision skill entirely

For a hexapod, I’d usually suggest:

  • use the ultrasonic sensor in a custom loop script
  • watch $Direction
  • only react when $Direction == "Forward" or when your forward action is running

That is often more predictable than trying to make the collision skill infer gait movement state.


Important note about ControlCommand()

Your example:

ControlCommand("Auto Position", "Action", "Stop")

may not be the best way to drive Auto Position depending on which exact commands that skill exposes in your project. For Auto Position, use the skill’s documented ControlCommands from its own config/actions, or trigger the specific action names consistently.

If you want, I can help you rewrite this into a clean JavaScript avoidance script that:

  • works with Six,
  • checks distance during reverse/turn,
  • and avoids the blocking behavior.

Good next questions

To narrow this down, can you tell me:

  1. Are you using Auto Position (Movement Panel) or the non-movement version?
  2. When you move forward manually, does $Direction show Forward?
  3. Do you want the avoidance logic to run inside the collision skill script, or would you prefer a standalone ARC script that you call from the skill?

Also, if you’re editing scripts a lot, the ARC AI Assistant built into ARC can help rewrite and convert this logic directly in the editor:
https://synthiam.com/Products/AI-Assistant

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.