# How to Set Up and Program Cruise Sequence Waypoints with Motion Tracking on ATOM Swing

> Learn to program ATOM Swing cruise sequence waypoints with motion tracking using the atomcam_tools firmware hack.ini file for automated camera control.

- Repository: [Mitsuru Nakada/atomcam_tools](https://github.com/mnakada/atomcam_tools)
- Tags: how-to-guide
- Published: 2026-03-07

---

**The atomcam_tools firmware enables automated cruise sequences through a semicolon-separated command list in [`hack.ini`](https://github.com/mnakada/atomcam_tools/blob/main/hack.ini), where `move`, `detect`, `follow`, and `sleep` commands drive the ATOM Swing camera through programmable waypoints with optional motion detection and object tracking.**

The mnakada/atomcam_tools project provides a complete **cruise sequence waypoints with motion tracking** system for ATOM Swing cameras. By combining a simple INI-based configuration, a Vue-based web editor, and native motion-detection hooks, the camera can autonomously patrol between positions, pause for events, and track moving objects in real time.

## Enabling Cruise Mode in hack.ini

Cruise functionality is controlled by the [`hack.ini`](https://github.com/mnakada/atomcam_tools/blob/main/hack.ini) file stored on the SD card (mounted at [`/tmp/hack.ini`](https://github.com/mnakada/atomcam_tools/blob/main//tmp/hack.ini) during runtime). To activate the feature, add the following line:

```ini
CRUISE=on

```

When the camera boots, the initialization script `/etc/init.d/S62webcontrol` starts [`cruise.sh`](https://github.com/mnakada/atomcam_tools/blob/main/cruise.sh) (line 9 of the init script). The shell script checks for `CRUISE=on` at line 13; if enabled, it enters an infinite loop that parses and executes the waypoint list.

## Programming Waypoint Sequences with CRUISE_LIST

The `CRUISE_LIST` parameter defines the patrol route as a semicolon-separated string of commands. Each command follows a strict syntax supported by the runtime engine in [`overlay_rootfs/scripts/cruise.sh`](https://github.com/mnakada/atomcam_tools/blob/main/overlay_rootfs/scripts/cruise.sh).

### Move Commands

Use the `move` command to position the camera before waiting or detecting motion:

```ini
move <pan> <tilt> [<speed>]

```

- **Pan**: 0–355 degrees
- **Tilt**: 0–180 degrees  
- **Speed**: Optional, 1 (slow) to 9 (fast)

### Detection and Tracking Modes

Two commands handle motion-aware pauses: `detect` and `follow`.

**Detect** pauses execution and waits for motion events:

```ini
detect <wait> <timeout>

```

The script calls the native `waitMotion` command (exposed via TCP port 4000) with the specified `wait` interval. If no motion occurs within `timeout` seconds, the cruise proceeds to the next waypoint.

**Follow** adds automatic tracking:

```ini
follow <wait> <timeout> [<speed>]

```

When motion is detected, the script issues an additional `move` command targeting the detected object's coordinates (extracted from the `waitMotion` response) using the specified speed.

### Sleep Intervals

For simple delays without motion handling, use:

```ini
sleep <wait>

```

### Configuration Example

A complete `CRUISE_LIST` that centers the camera, watches for motion, shifts to a new angle, tracks any detected object at high speed, then rests:

```ini
CRUISE=on
CRUISE_LIST=move 180 90;detect 5 10;move 210 90;follow 5 10 8;sleep 10;

```

## Motion Tracking Implementation Details

The motion-tracking pipeline spans three layers: the shell script controller, the native command handler, and the video OSD callback.

### waitMotion Command Handler

When [`cruise.sh`](https://github.com/mnakada/atomcam_tools/blob/main/cruise.sh) executes `waitMotion <timeout>`, it sends the string over localhost port 4000. The `WaitMotion` function in [`libcallback/wait_motion.c`](https://github.com/mnakada/atomcam_tools/blob/main/libcallback/wait_motion.c) (line 35) registers the requesting file descriptor (`WaitMotionFd`) and stores the timeout value. The function returns `NULL` to keep the socket open until motion occurs or the timer expires.

### OSD Callback Integration

Each video frame triggers `local_sdk_video_osd_update_rect`. The hook in [`wait_motion.c`](https://github.com/mnakada/atomcam_tools/blob/main/wait_motion.c) (line 55) checks if a motion request is pending (`WaitMotionFd >= 0`). If the camera motors have been idle for at least 0.5 seconds, the callback reads the current pan/tilt position and the motion-rectangle coordinates, then builds a response string:

```

detect <left> <right> <top> <bottom> <pan> <tilt>

```

This string is sent back to [`cruise.sh`](https://github.com/mnakada/atomcam_tools/blob/main/cruise.sh) via `CommandResponse` (line 84). If no motion is present, the callback transmits `"clear"`.

### Cruise Script Logic

Inside [`cruise.sh`](https://github.com/mnakada/atomcam_tools/blob/main/cruise.sh), the `follow` block parses the response (stored in variable `motion`). If the response starts with `"detect"`, the script extracts the sixth and seventh fields (`$6 $7`) representing the target pan and tilt, then issues:

```sh
echo "move $6 $7 $speed" | nc localhost 4000

```

If `waitMotion` returns `"timeout"`, the loop breaks and the script advances to the next waypoint in `CRUISE_LIST`.

## Web UI Configuration

While manual INI editing works, the Vue-based interface provides a graphical editor. The component [`web/source/vue/SettingCruise.vue`](https://github.com/mnakada/atomcam_tools/blob/main/web/source/vue/SettingCruise.vue) renders individual waypoint rows for setting pan, tilt, speed, wait times, and detection modes. The parent [`Setting.vue`](https://github.com/mnakada/atomcam_tools/blob/main/Setting.vue) (around line 1306) serializes the waypoint array back into the semicolon-separated `CRUISE_LIST` string before writing to [`hack.ini`](https://github.com/mnakada/atomcam_tools/blob/main/hack.ini).

## Debugging and Log Files

The cruise engine logs all activity to `/tmp/log/cruise.log` (line 65 of [`cruise.sh`](https://github.com/mnakada/atomcam_tools/blob/main/cruise.sh)). Each executed command and motion event is timestamped, allowing verification that waypoints are reached and that `waitMotion` responses are received correctly.

## Summary

- **Enable cruise mode** by setting `CRUISE=on` in [`/tmp/hack.ini`](https://github.com/mnakada/atomcam_tools/blob/main//tmp/hack.ini) on the SD card.
- **Define waypoints** using the `CRUISE_LIST` syntax with `move`, `detect`, `follow`, and `sleep` commands.
- **Motion tracking** relies on the `waitMotion` command registered in [`libcallback/command.c`](https://github.com/mnakada/atomcam_tools/blob/main/libcallback/command.c) and implemented in [`libcallback/wait_motion.c`](https://github.com/mnakada/atomcam_tools/blob/main/libcallback/wait_motion.c), which bridges OSD motion rectangles with shell-scriptable camera movements.
- **Speed values** range from 1 (slow) to 9 (fast) for motorized moves.
- **Logs** are written to `/tmp/log/cruise.log` for troubleshooting sequence execution.

## Frequently Asked Questions

### Which camera models support cruise waypoints and motion tracking?

The cruise feature is exclusive to the **ATOM Swing** model, as it requires motorized pan/tilt hardware. The motion-tracking logic specifically depends on the `local_sdk_video_osd_update_rect` callback available in the Swing’s firmware variant.

### Can I run a cruise sequence without motion detection?

Yes. Omit `detect` and `follow` commands from `CRUISE_LIST` and use only `move` and `sleep` commands. The camera will patrol between angles and pause for fixed intervals without invoking the `waitMotion` handler.

### What are the valid ranges for pan, tilt, and speed values?

According to the parser in [`cruise.sh`](https://github.com/mnakada/atomcam_tools/blob/main/cruise.sh), **pan** accepts 0–355 degrees, **tilt** accepts 0–180 degrees, and **speed** accepts 1–9. Values outside these ranges may cause the motor driver to ignore the command or return an error over the command socket.

### Why does motion tracking fail to trigger even when movement is visible?

First, verify that motion detection is enabled in the camera’s base settings and that the OSD rectangle is being drawn. The [`wait_motion.c`](https://github.com/mnakada/atomcam_tools/blob/main/wait_motion.c) hook requires the camera motors to be idle for at least 0.5 seconds before reporting coordinates; if the camera is still moving from a previous `move` command, the callback will not fire. Check `/tmp/log/cruise.log` to confirm that `waitMotion` calls are being issued and whether `"timeout"` or `"detect"` responses are returned.