Skip to navigation

Launchers and command-line options

View as Markdown

The Safety Core is started in one of three ways:

LauncherWhere it runsWhat it starts
launch_hoisa.shOn the host. Installed by the psf-desktop and psf-tegra Debian packages at /opt/nvidia/psf/bin/launch_hoisa.shThe whole stack: the Safety Core container (or the same processes on the host), the SDMs or fsicom-agent, SAIM and PCM
The container entrypointInside the Safety Core container (/opt/nvidia/psf/bin/launch_psf.sh)The SEI daemon, the NvPSD Gateway, the MDX client, SAIM, PCM and, unless told otherwise, the SDMs
The binaries directlyWherever you start themOne process each

The Deployment Guide starts the container directly, with the SDMs inside it; see Container options. launch_hoisa.sh runs the SDMs on the host instead; see What runs where.

Both launchers take the mode of each AI monitor on the command line, --saim-mode and --pcm-mode. When they start the control plane, they check those modes against required_safety_monitor and required_perception_monitor in nvpss.conf, and they read the deployment topology from deploymentMode. They never change nvpss.conf. See Monitor modes and SEI Configuration.

launch_hoisa.sh

sudo /opt/nvidia/psf/bin/launch_hoisa.sh --saim-mode <learn|active|skip> --pcm-mode <learn|active|skip> [options]

Requirements

  • Root or passwordless sudo. The launcher uses sudo -n to create /var/log/psf, its log files, the baseline directories of a learning monitor and /run/nvpsf, and to start the host processes of a control-plane run. Without it the launcher stops with Error: cannot create /var/log/psf; run as root or configure passwordless sudo.

  • Docker access for --runtime docker (the default). A control-plane run checks that Docker is installed, that a docker group exists and that the user can reach the Docker daemon, and stops with Error: docker is not installed or not in PATH, Error: 'docker' group does not exist or Error: cannot connect to the Docker daemon (is the user in the 'docker' group?). A learning run checks only that Docker is installed.

  • A readable nvpss.conf in a control-plane run, with deploymentMode, required_safety_monitor and required_perception_monitor. The launcher parses the two required-monitor keys as strictly as the daemon does, before it starts anything. A learning run does not read the file.

  • /run/nvpsf, in a control-plane run. The launcher creates it if it is missing and sets mode 1777. It refuses a symlink and a directory it cannot write. Under --runtime docker the directory must also be writable by other users, because the container writes to it as a different user. A mode other than 1777 is a warning only.

  • One primary group for every Safety Core process (see Shared process group). With --runtime host every connecting process runs as root. With --runtime docker the launcher starts the SDMs and fsicom-agent with the container user’s group; see Host processes and the container’s group. For that, a control-plane run with --runtime docker also needs:

    • setpriv, from util-linux, runnable through passwordless sudo, or the launcher stops with Error: 'sudo -n setpriv' is not available; install util-linux and allow setpriv for passwordless sudo, so host PSF processes can start with the container's group;
    • Docker without user-namespace remapping and not in rootless mode, or the launcher stops with Error: Docker user-namespace remapping/rootless mode is not supported: host PSF processes must share the container's GID. It reads this from docker info, and stops with Error: cannot read the Docker security options (docker info) if it cannot.

    The launcher checks both before it starts anything.

  • Kernel socket buffers large enough for the gateway link. See Kernel socket buffers.

  • For --sdm-target fsi: the FSI firmware flashed and the nvFsiCom daemon running. The launcher does not start nvFsiCom. See SDM on FSI.

Monitor modes

--saim-mode and --pcm-mode are both required, and each selects one monitor only.

ModeWhat the monitor does
learnRecords baselines for --learn-duration seconds, then exits. It never switches to active. SAIM writes one <sensorName>_baseline.cfg per camera into --baseline-dir. PCM writes one pcm_baseline.cfg for the whole camera set into --pcm-baseline-dir. A learning monitor does not register with the SEI daemon.
activeRegisters with the SEI daemon and reports its verdicts, using the saved baselines.
skipNot started. Its configuration and baselines are not checked.

The two modes together decide what kind of run it is:

ModesRunWhat runs
At least one monitor active, or both skipControl-plane runThe SEI daemon, the NvPSD Gateway, the MDX client, the SDMs or fsicom-agent, and every monitor that is not skipped. A monitor in learn stops when its baselines are written; the rest keeps running until you stop the launcher.
Only learn and skipLearning runThe learning monitors only. No SEI daemon, NvPSD Gateway, MDX client or SDM starts, and nvpss.conf is not read. The launcher exits when every learning monitor has finished.

Required sources. A monitor in learn or skip reports nothing to the SEI daemon, so the daemon must not require it. In a control-plane run the launcher checks:

Key in nvpss.confValue for activeValue for learn or skip
required_safety_monitor10
required_perception_monitor10

A mismatch stops the launcher before anything starts, for example:

Error: --pcm-mode skip conflicts with required_perception_monitor = 1 in /opt/nvidia/psf/bin/nvpss.conf.
Set required_perception_monitor = 0 for this mode, or select the mode matching the deployment's required sources.

A missing key gives Error: <key> is missing from <file>., a repeated key Error: <key> is defined more than once in <file>. Keep exactly one., and any value other than 0 or 1 Error: <key> = '<value>' in <file> is not 0 or 1. When the keys match, the launcher prints Required sources: safety_monitor=<n> perception_monitor=<n> (from <file>). To change what a site requires, edit the file named by --nvpss-conf; the launcher never rewrites it.

Missing or invalid mode. Error: --saim-mode is required and must be learn, active, or skip, or the same with --pcm-mode.

Options

“Applies to” names the runs in which the option has an effect. A control-plane run and a learning run are defined in Monitor modes.

OptionApplies toDefaultValues and effect
--saim-mode <learn|active|skip>every runnone, requiredSAIM’s mode. See Monitor modes.
--pcm-mode <learn|active|skip>every runnone, requiredPCM’s mode. See Monitor modes.
--mode <learn|active|skip>every runnoneDeprecated alias for --saim-mode. It never sets PCM’s mode. Prints Warning: --mode is deprecated; use --saim-mode (PCM requires its own --pcm-mode). A different --saim-mode on the same line: Error: --mode conflicts with --saim-mode.
--skip-pcmevery runoffDeprecated alias for --pcm-mode skip. Prints Warning: --skip-pcm is deprecated; use --pcm-mode skip. With another --pcm-mode: Error: --skip-pcm conflicts with --pcm-mode <mode>.
--sensor-config <file>control-plane runs, and runs where SAIM is not skippednoneThe camera list (pipelineId, sensorName, rtspUrl). Required in those runs: Error: --sensor-config is required, or Error: sensor config file '<file>' not found. SAIM reads it. Under --runtime docker it is mounted into the container at /opt/nvidia/psf/bin/sensor_config.conf; with --runtime host it is also passed to the MDX client in 2D. See sensor_config.conf.
--docker-image <image:tag>every run with --runtime dockernoneRequired with --runtime docker, also in a learning run: Error: --docker-image <image:tag> is required with --runtime docker (use --runtime host to run on the host). Ignored with a warning under --runtime host.
--runtime <docker|host>every rundockerWhere the SEI daemon, NvPSD Gateway, MDX client, SAIM and PCM run. See What runs where. Any other value: Error: --runtime must be 'docker' or 'host'.
--app <value>control-plane runs; learning runs with PCMatlControl-plane run: the decision maker or makers to run, in instance order. See Applications. Learning run: the application whose shipped event mapping PCM records rules from, when --app or --sdm-config is given. Give the same value as in the active run; see PCM baselines.
--cmd-rx-ip <ip>control-plane runsnone, requiredAddress of the command receiver (the PLC). Passed to every SDM, or to fsicom-agent as --ip. Missing: Error: --cmd-rx-ip is required in active mode. Ignored with a warning in a learning run.
--cmd-rx-port <port[,port]>control-plane runsnone, requiredOne command receiver port per SDM, in --app order, each 1–65535. Two SDMs need different ports. Missing: Error: --cmd-rx-port is required in active mode. Ignored with a warning in a learning run.
--sdm-config <file[,file]>control-plane runs; learning runs with PCMnoneOne SDM configuration file per SDM, in --app order. Host paths, also with --runtime docker, because the SDMs run on the host. Required for every CCPLEX ATL or Proximity SDM. Not accepted with --sdm-target fsi. When PCM runs, the files are also given to PCM, which records or checks the event codes they bind; under --runtime docker they are mounted read-only into the container as /opt/nvidia/psf/bin/pcm_sdm_<n>.conf, <n> counting from 0. See SDM configuration files and PCM baselines.
--sdm-log-file <file[,file]>control-plane runs<app>_sdm.log per SDMOne log file per SDM, in --app order. A relative path is placed under /var/log/psf. See Logs.
--event-mapping <file>control-plane runs; learning runs with PCMthe application’s shipped mappingOverrides the MDX client event mapping. PCM reads the same mapping. With --runtime docker the file is mounted read-only into the container. See Event Mapping Configuration.
--atl-zone1-conf <file>control-plane runs; learning runs with PCMnoneOlder form of --sdm-config for the first ATL SDM. Cannot be combined with --sdm-config.
--atl-zone2-conf <file>control-plane runs; learning runs with PCMnoneOlder form of --sdm-config for the second ATL SDM (--app atl_dual or atl,atl).
--zone2-cmd-rx-port <port>control-plane runsnoneOlder form of the second port in --cmd-rx-port, for --app atl_dual or atl,atl. Cannot be combined with a port list.
--sdm-target <ccplex|fsi>control-plane runsccplexccplex: run the SDM binaries on the host. fsi: run fsicom-agent instead; the SDM runs on the Functional Safety Island. FSI supports a single atl or pxc SDM only. Ignored with a warning in a learning run.
--sensor-pipelines-config <file>control-plane runsthe SDMs’ default, /opt/nvidia/psf/bin/sensor_pipelines_config.confThe reviewed sensor set. Optional, although the help text lists it under “Required”. When given, it is passed to every CCPLEX SDM, and to the MDX client in 3D with --runtime host. In 3D the launcher checks that the file, or the default, is readable. See sensor_pipelines_config.conf.
--nvpss-conf <file>control-plane runs/opt/nvidia/psf/bin/nvpss.confThe nvpss.conf the launcher checks and the daemon uses. With --runtime docker it is mounted read-only over /opt/nvidia/psf/bin/nvpss.conf in the container. With --runtime host it is passed to nvpss_daemon as --conf. A non-default value is ignored with a warning in a learning run.
--threshold-config <file>runs with SAIM active/opt/nvidia/psf/bin/thresholds.cfgSAIM thresholds. With --runtime host, passed to SAIM. With --runtime docker, a file other than the default is mounted read-only over the image’s /opt/nvidia/psf/bin/thresholds.cfg; otherwise the image’s copy is used.
--baseline-dir <dir>runs where SAIM is not skipped/opt/nvidia/psf/bin/saim_baselineHost directory of SAIM’s per-camera baselines. A learning run creates it with mode 0755 and refuses a path that resolves through a symlink; under --runtime docker the container then makes it owned by its nvidia user. With --runtime docker it is mounted as SAIM’s working directory, writable for learn and read-only for active. Use the same directory in both runs. See Default baselines.
--pcm-baseline-dir <dir>runs where PCM is not skipped/opt/nvidia/psf/bin/pcm_baselineHost directory of PCM’s baselines. A learning run creates it as it creates --baseline-dir. It must be a readable directory: Error: PCM baseline dir '<dir>' is not readable; install defaults or run LEARN. With --runtime docker it is mounted at /opt/nvidia/psf/bin/pcm_baseline, writable for learn and read-only for active. Use the same directory in both runs.
--pcm-config <file>runs with PCM active/opt/nvidia/psf/bin/pcm_monitor.cfgPCM’s monitor configuration (containers to check, which checks run, timing). With --runtime host, or when the option is given, the file must be readable: Error: PCM config '<file>' not found or not readable. With --runtime docker, a file given with this option is mounted read-only over /opt/nvidia/psf/bin/pcm_monitor.cfg in the container; without it the image’s copy is used. See Perception Monitor.
--learn-duration <seconds>runs with a learning monitor300How long each learning monitor records. Integer 1–3600, checked in every run: Error: --learn-duration must be an integer in [1, 3600].
--gpu <id>runs where SAIM is not skippednone: streams are spread across the visible GPUsPins every SAIM stream to one GPU. With --runtime docker only 0 works; see Known Limitations.
--kafka-broker <host:port>control-plane runs; learning runs with PCMthe MDX client and PCM defaultsPassed to the MDX client as --broker and to PCM as --kafka-broker. Under --runtime docker it is passed to the container as --broker, which gives it to both. In a learning run with PCM skipped it is ignored with a warning.
--container-name <name>every run with --runtime dockernv-psfName of the Safety Core container, in learning and control-plane runs. An existing container of that name is removed first. Ignored under --runtime host.
--decision_interval_ms <ms>control-plane runs0 (off)Period at which a CCPLEX SDM repeats its last decision to the PLC. 0, or an integer 100–36000. Ignored with a warning for --sdm-target fsi and in a learning run.
--hb_stale_ms <ms>control-plane runs5000NvPSD Gateway heartbeat stale grace of the CCPLEX SDMs. Integer 100–600000. Ignored with a warning for --sdm-target fsi.
--hb_period_ms <ms>control-plane runs5500NvPSD Gateway heartbeat miss period of the CCPLEX SDMs. Integer 100–600000. Ignored with a warning for --sdm-target fsi.
--halo-ip <ip>control-plane runsnone (off)When set, proximity_sdm also sends every decision command to a VST halo-overlay listener at this address. Needs exactly one Proximity SDM (pxc, atl,pxc or pxc,atl): Error: --halo-ip/--halo-port require one PXC instance.
--halo-port <port>control-plane runs12346Port of the halo-overlay listener, 1–65535.
--gateway-ip <ip>—127.0.0.1No effect. See Options with no effect.
--gateway-port <port>—50000No effect, but must be 1–65535. See Options with no effect.
-h, --help——Prints the usage text and exits with status 0.

Every option that takes a value rejects a missing value, or a value starting with --, with Error: <option> requires an argument. An unknown option prints Error: unknown option '<option>' and the usage text, and the launcher exits with status 1. An option ignored in a learning run prints a warning of the form Warning: <option> is ignored in learn mode.

The environment variables PCM_BASELINE_CONFIG (its directory part) and PCM_MONITOR_CONFIG, when set in the launcher’s environment, replace the defaults of --pcm-baseline-dir and --pcm-config.

Options with no effect

--gateway-ip and --gateway-port are parsed, and --gateway-port is range-checked, but neither value reaches any process. The NvPSD Gateway listens on no IP address or UDP port: every SDM connects to it through /run/nvpsf/nvpsd_gateway. A non-default value makes the launcher print a warning that mentions a “preflight UDP port check”; no such check runs. Leave both options out.

Applications

--appSDMs started on the host (CCPLEX), in instance orderDefault MDX mappingDefault SDM logsFSI
atl (default)atl_sdm/opt/nvidia/psf/apps/atl/event_mapping_atl.pb.txtatl_sdm.logyes
pxcproximity_sdm/opt/nvidia/psf/apps/proximity/proximity_event_mapping.pb.txtpxc_sdm.logyes
atl,pxcatl_sdm, then proximity_sdmproximity_event_mapping.pb.txtatl_sdm.log, pxc_sdm.logno
pxc,atlproximity_sdm, then atl_sdmproximity_event_mapping.pb.txtpxc_sdm.log, atl_sdm.logno
atl,atltwo atl_sdm, one per zoneevent_mapping_atl.pb.txtatl_sdm_zone1.log, atl_sdm_zone2.logno
atl_dualthe same as atl,atlevent_mapping_atl.pb.txtatl_sdm_zone1.log, atl_sdm_zone2.logno
pxc,pxctwo proximity_sdmproximity_event_mapping.pb.txtpxc_sdm_zone1.log, pxc_sdm_zone2.logno

All the SDMs of one launch share one NvPSD Gateway and one MDX client. Any other value is refused with Error: unsupported app '<value>'. launch_hoisa.sh has no atl_proximity value; the combined forklift and proximity application is started through the container entrypoint only. Multi-SDM values are refused with --sdm-target fsi: Error: multi-SDM combinations support --sdm-target ccplex only.

SDM configuration files

Every CCPLEX ATL and Proximity SDM needs a configuration file that binds its situations to event codes. The package installs editable templates in /opt/nvidia/psf/bin/:

TemplateForBinds
atl_sdm_zone1.conf.samplethe first (or only) ATL SDMEVENT_0–EVENT_5
atl_sdm_zone2.conf.samplethe second ATL SDMEVENT_6–EVENT_11
pxc_sdm_forklift.conf.samplea single Proximity SDM, or the Proximity SDM next to ATLforklift–person pairs, EVENT_12–EVENT_14
pxc_sdm_robots.conf.samplethe second Proximity SDMrobot–person pairs, EVENT_15–EVENT_23

Copy a template, edit it, and pass the copy with --sdm-config. The event codes must match the output_event values of the mapping the MDX client runs. The launcher checks that each file is readable (Error: SDM <n> config '<path>' is not a readable file), that the list has one entry per SDM (Error: --sdm-config needs <n> value(s), in the same order as --app), and that two SDMs do not share an event code (Error: SDM configs overlap on EVENT_<n>; use distinct application event codes). The SDM binary validates the keys inside each file at startup; see Binary command lines. In a learning run with PCM, an unreadable file gives Error: PCM SDM config '<path>' is not readable.

What runs where

Process--runtime docker--runtime host
nvpss_daemon, nvpsd_gateway, mdx_client (control-plane runs)In the container, as its user nvidiaOn the host, as root
atl_sdm and proximity_sdm, or fsicom-agent (control-plane runs)On the host, as root, with the container user’s group as primary groupOn the host, as root
safety_monitor (SAIM), unless skippedIn the containeractive: on the host, as root. learn: on the host, as the user running the launcher. Both in --baseline-dir
nv_perception_monitor (PCM), unless skippedIn the containeractive: on the host, as root. learn: on the host, as the user running the launcher

Under --runtime docker, a learning run starts one container in the foreground, with --rm, for both learning monitors, and the launcher returns when that container exits. A control-plane run starts the container in the background; the monitors start inside it after its control plane. Under --runtime host, a learning monitor needs write access to its baseline directory as the user running the launcher, or the launcher stops with Error: <SAIM|PCM> baseline dir '<dir>' is not writable for LEARN; grant write access or run LEARN under sudo.

Every host process that the launcher starts with sudo -n runs as root. Under --runtime host they run with group ID 0, and every connecting process is such a host process, so they all share one primary group. Under --runtime docker the processes in the container run as the container user nvidia, with that user’s group, and the launcher starts the SDMs and fsicom-agent on the host with that group; see Host processes and the container’s group.

Host processes and the container’s group

In a control-plane run with --runtime docker, once the container is running and before it starts any SDM or fsicom-agent, the launcher reads the group ID of the container user with docker exec <container-name> id -g nvidia and prints:

Host PSF processes run with the container's GID <gid> (user nvidia in <container-name>)

It then starts each SDM, or fsicom-agent, as sudo -n setpriv --regid <gid> --keep-groups -- env .... The process keeps root’s user ID and supplementary groups; only its primary group changes. --runtime host is unchanged: it starts the control plane, the SDMs or fsicom-agent, and a monitor in active with sudo -n env ..., and a monitor in learn as the user running the launcher. A learning run with --runtime docker starts no process on the host.

The launcher stops, and removes the container, before any host process starts, if it cannot use the group ID:

MessageCause
Error: cannot read the GID of user nvidia in container <container-name>docker exec failed, or the image has no nvidia user
Error: container <container-name> runs PSF processes with GID '<gid>', which cannot be used for host peersThe group ID is not a number from 1 to 4294967294, or it is the kernel’s overflow group ID (/proc/sys/kernel/overflowgid, usually 65534). Group 0 would admit every root process, and the overflow ID is what a process with an unmapped group reports

It then checks whether host accounts share the container user’s IDs, and warns without stopping:

Warning: GID <gid> of the Safety Core container is also used on this host by a group with <m> member(s) and as the primary group of <k> user(s).
Accounts that can run with GID <gid> can connect to, or stand in for,
the Safety Core sockets in /run/nvpsf. List them with: getent group <gid>; getent passwd | awk -F: '$4 == <gid>'
Warning: UID <uid> of the Safety Core container belongs to <j> host account(s).
They own the Safety Core sockets in /run/nvpsf on this host and can
delete them. List them with: getent passwd <uid>

The first warning names only the clauses that apply: a host group with the ID, users whose primary group it is, or both. A group count it cannot compute is shown as ?. If the user ID cannot be read, the launcher prints Warning: cannot read the UID of user nvidia in container <container-name>; UID overlap not checked. The warnings give counts and lookup commands, never account or group names. What the overlap allows, and how to remove it, is described in Host accounts with the container’s group.

In a control-plane run the launcher starts, in order: the container (or, with --runtime host, the SEI daemon, then the NvPSD Gateway, then the MDX client), the SDMs or fsicom-agent, and, with --runtime host, the monitors that are not skipped. It waits 1 s after each SDM and each host control-plane process and stops with Error: failed to start <process> if the process has already exited. It waits 2 s after starting the container and stops with Error: Docker container <name> failed to start, followed by the container’s output, if the container is no longer running. Under --runtime docker it then prints Monitors run inside <name>: SAIM=<mode>, PCM=<mode>. A host monitor prints <SAIM|PCM> started in <LEARN|ACTIVE> mode with PID <pid>, or Skipping <SAIM|PCM> (--<saim|pcm>-mode skip). The MDX client is started as instance 1. In 2D it gets the camera list; in 3D it gets the reviewed sensor set.

With --sdm-target fsi the launcher starts fsicom-agent as:

fsicom-agent --heartbeat --relay-fsi-resp --ip <cmd-rx-ip> --port <cmd-rx-port> \
--cmd-identifier <0xA2 for atl, 0xA5 for pxc>

What it mounts into the container

Control-plane run, --runtime docker:

docker run argumentPurpose
-v <--sensor-config>:/opt/nvidia/psf/bin/sensor_config.conf:roThe camera list
-v <--nvpss-conf>:/opt/nvidia/psf/bin/nvpss.conf:roThe SEI configuration
-v /run/nvpsf:/run/nvpsfThe socket directory shared by every Safety Core process
-v /var/log/psf/psf.log:/var/log/psf/psf.logThe container’s syslog stream
-v /var/run/docker.sock:/var/run/docker.sock and --group-add <docker gid>The host’s Docker daemon, which PCM’s container-health check queries
--network=hostThe container shares the host network, for example to reach a Kafka broker on the host
--ipc=hostNot needed by the Safety Core
-v /var/log/psf/saim.log:/var/log/psf/saim.logSAIM output, unless SAIM is skipped
-v <--baseline-dir>:/opt/nvidia/psf/bin/saim_baseline:ro (:rw for SAIM learn)SAIM baselines, unless SAIM is skipped
x86-64: --gpus all. aarch64: --runtime nvidia -e NVIDIA_VISIBLE_DEVICES=all, plus --group-add for the host video and render groupsGPU, decoder and PVA access for SAIM, unless SAIM is skipped
-e NVIDIA_DRIVER_CAPABILITIES=compute,utility,videoThe same
-v <--threshold-config>:/opt/nvidia/psf/bin/thresholds.cfg:roOnly when SAIM is active and --threshold-config names a non-default file
-v /var/log/psf/pcm.log:/var/log/psf/pcm.logPCM output, unless PCM is skipped
-v <--pcm-baseline-dir>:/opt/nvidia/psf/bin/pcm_baseline:ro (:rw for PCM learn)PCM baselines, unless PCM is skipped
-v <--pcm-config>:/opt/nvidia/psf/bin/pcm_monitor.cfg:roOnly when PCM is active and --pcm-config is given
-v <--sdm-config n>:/opt/nvidia/psf/bin/pcm_sdm_<n>.conf:roThe SDM configurations, read by PCM, unless PCM is skipped
-v <--event-mapping>:/opt/nvidia/psf/bin/sdm_event_mapping.pb.txt:roOnly when --event-mapping is given

The container arguments are --app <app>, then, for ATL and Proximity applications, --sdm-external --cmd_rx_port <ports>, then --cmd_rx_ip <ip>, --sensor-config /opt/nvidia/psf/bin/sensor_config.conf, --saim-mode <mode> --pcm-mode <mode> --learn-duration <seconds>, plus --event-mapping, --sdm-config, --broker, --pcm-baseline-dir, --baseline-dir and --gpu when they apply. SAIM and PCM therefore do not cross the container boundary; the SDMs and fsicom-agent on the host do, through /run/nvpsf, with the container user’s group (see Host processes and the container’s group).

Learning run, --runtime docker: the launcher runs the container in the foreground with --rm, and --network=host. For a learning SAIM it adds the GPU arguments above, the camera list, the SAIM baseline directory (writable) and saim.log. For a learning PCM it adds the PCM baseline directory (writable) and pcm.log, and, when PCM records event bindings, the event mapping as /opt/nvidia/psf/bin/pcm_event_mapping.pb.txt and each SDM configuration as /opt/nvidia/psf/bin/pcm_sdm_<n>.conf, all read-only. It passes --saim-mode <mode> --pcm-mode <mode> --learn-duration <seconds> and the matching container paths. A learning run mounts neither nvpss.conf nor the Docker socket, and prints Launching learners: SAIM=<mode>, PCM=<mode> (Docker).

The container does not receive sensor_pipelines_config.conf or the 3D sensor group file. See Known Limitations.

Logs

All files are under /var/log/psf/. The launcher creates psf.log and the SDM logs in a control-plane run, and saim.log and pcm.log for each monitor that is not skipped, all with mode 0666. SAIM and PCM output is appended to saim.log and pcm.log across runs.

FileContents
psf.log--runtime docker: the container’s syslog stream, which holds the records of the SEI daemon, the NvPSD Gateway and the MDX client. --runtime host: the console output of those three processes. In both runtimes, also the console output of the CCPLEX SDMs.
pss.log--runtime host only: the syslog records of the SEI daemon, the NvPSD Gateway and the MDX client, written by the package’s rsyslog rule.
atl_sdm.log, pxc_sdm.log, atl_sdm_zone1.log, …Each CCPLEX SDM’s own log (--sdm-log-file). With --sdm-target fsi, the first of these holds the output of fsicom-agent, and the SDM itself logs to the FSI UART.
saim.logSAIM output, in both runtimes
pcm.logPCM output, in both runtimes

With --runtime docker, docker logs <container-name> also shows the container’s syslog stream and the console output of every process in the container, including SAIM and PCM. The launcher removes the container when it stops, and its output with it; the files above remain.

Supervision, shutdown and exit status

While a control-plane run is up, the launcher checks every 2 s that each host process and each host monitor is alive and, under --runtime docker, that the container is still running. The first failure stops the run:

FailureMessage
A host SDM, fsicom-agent or host control-plane process exitedHost process <pid> exited unexpectedly
The container stopped, for example because a process in it exitedError: PSF Docker container exited unexpectedly
A host monitor in active exited, with any statusError: <SAIM|PCM> exited (status <n>)
A host monitor in learn exited with a non-zero statusError: <SAIM|PCM> exited (status <n>)
A host monitor’s log file can no longer be writtenError: <SAIM|PCM> log writer exited (status <n>)

A learning monitor that exits with status 0 prints <SAIM|PCM> completed LEARN successfully and the run continues. A host learning run that succeeds prints All selected monitors completed LEARN successfully.

SIGINT (Ctrl-C) or SIGTERM stops the host monitors and every host process with SIGTERM, waits up to 10 s, sends SIGKILL to any that remain, then stops and removes the container. The launcher prints Cleanup complete last.

Exit statusWhen
0--help, or a learning run in which every learning monitor succeeded
1A validation or prerequisite failure, a failed learning monitor, or any failure in the table above
130Interrupted by SIGINT
143Terminated by SIGTERM

Default baselines (running active mode without learn)

SAIM. The package installs three SAIM baseline templates in /opt/nvidia/psf/bin/saim_baseline, tuned for the loading-dock reference scene: Camera_baseline.cfg.default, Camera_01_baseline.cfg.default and Camera_02_baseline.cfg.default.

In active mode SAIM looks, for each camera, for <sensorName>_baseline.cfg in its working directory (the baseline directory). If that file is missing, it uses <sensorName>_baseline.cfg.default and prints Notice: baseline '<file>' not found for sensor '<name>'; falling back to default '<file>.default'. If neither exists, SAIM stops with Error: baseline file '<file>' (or '<file>.default') not found for sensor '<name>'. The fallback matches sensorName exactly, so a site whose camera names differ from the three above must learn SAIM baselines. The templates were learned at 1920×1080, so they also need cameras of that size, and they are tied to the release: under the Docker runtime the container reads the host’s templates, so install the package of the same release as the image.

When SAIM is active, the launcher checks, before it starts anything, that the baseline directory holds at least one *_baseline.cfg or *_baseline.cfg.default file: Error: no SAIM baselines found in '<dir>'; run --saim-mode learn first. The container entrypoint checks again before it starts SAIM: Error: no SAIM baselines (*_baseline.cfg or *_baseline.cfg.default) found in '<dir>'.

PCM. A learning PCM writes one pcm_baseline.cfg into --pcm-baseline-dir. Besides the cameras it saw on mdx-frames and their timing, the file records the decision contract: the ROI and proximity rules of the event mapping that the SDM configurations select. With --app but no SDM configuration, as for --sdm-target fsi, PCM records every rule of the application’s mapping. With none of --app, --sdm-config and --event-mapping, it records cameras and timing only.

An active PCM compares the recorded contract with the contract of its own run and does not use a baseline whose contract differs, logging DVM: decision mapping changed for <camera>; baseline not used, re-run LEARN. When the run has a contract, as an ATL or Proximity application does, a pcm_baseline.cfg record learned without one is not used either; older per-camera baseline files are still used. With no usable baseline PCM runs without its data check; it does not report the AI pipeline invalid for this. Learn PCM baselines with the same --app, --sdm-config (or --atl-zone*-conf) and --event-mapping as the active run.

The package installs reference templates in /opt/nvidia/psf/bin/pcm_baseline: pcm_Camera_baseline.cfg.default, pcm_Camera_01_baseline.cfg.default and pcm_Camera_02_baseline.cfg.default. They were learned on the loading-dock reference scene with proximity_event_mapping.pb.txt, atl_sdm_zone1.conf and pxc_sdm_forklift.conf, so they fit --app atl,pxc with unchanged copies of those two configurations, on the reference cameras, and only while no learned pcm_baseline.cfg is in the directory. Any other application needs a learning run. How PCM chooses between the learned file and the templates is described in Perception Monitor.

PCM logs what it loaded at startup, as DVM: baseline loaded, cameras=<n>, decision-data profiles=<n> (from <dir>) and checks: container_health=<on|off> (...) data_validation=<on|off> (...).

The baseline templates fit the loading-dock reference cameras only. For any other camera or scene, learn SAIM and PCM baselines: the defaults can produce wrong trust verdicts elsewhere.

Examples

Learn both monitors in the container, then run the forklift safety function with the control plane and the monitors in the container and the SDM on the host:

sudo /opt/nvidia/psf/bin/launch_hoisa.sh --saim-mode learn --pcm-mode learn --app atl \
--sensor-config /opt/nvidia/psf/bin/sensor_config.conf \
--sdm-config /opt/nvidia/psf/bin/atl_sdm_zone1.conf \
--docker-image nvcr.io/nvidia/halos-outside-in/outside-in-safety:nv-psf-halos-1.4-6b92731 \
--learn-duration 300
sudo /opt/nvidia/psf/bin/launch_hoisa.sh --saim-mode active --pcm-mode active --app atl \
--sensor-config /opt/nvidia/psf/bin/sensor_config.conf \
--sdm-config /opt/nvidia/psf/bin/atl_sdm_zone1.conf \
--docker-image nvcr.io/nvidia/halos-outside-in/outside-in-safety:nv-psf-halos-1.4-6b92731 \
--cmd-rx-ip <cmd-rx-ip> --cmd-rx-port 12345

The same run with every process on the host:

sudo /opt/nvidia/psf/bin/launch_hoisa.sh --saim-mode active --pcm-mode active --runtime host --app atl \
--sensor-config /opt/nvidia/psf/bin/sensor_config.conf \
--sdm-config /opt/nvidia/psf/bin/atl_sdm_zone1.conf \
--cmd-rx-ip <cmd-rx-ip> --cmd-rx-port 12345

Forklift safety function and Proximity Monitoring together, on the host. On the reference cameras, with unchanged copies of the templates and no learned pcm_baseline.cfg, PCM uses the reference baselines:

sudo /opt/nvidia/psf/bin/launch_hoisa.sh --saim-mode active --pcm-mode active --runtime host --app atl,pxc \
--sensor-config /opt/nvidia/psf/bin/sensor_config.conf \
--sdm-config /opt/nvidia/psf/bin/atl_sdm_zone1.conf,/opt/nvidia/psf/bin/pxc_sdm_forklift.conf \
--cmd-rx-ip <cmd-rx-ip> --cmd-rx-port 12345,12346

Forklift safety function with the SDM on the FSI, on the host:

sudo /opt/nvidia/psf/bin/launch_hoisa.sh --saim-mode active --pcm-mode active --runtime host --app atl --sdm-target fsi \
--sensor-config /opt/nvidia/psf/bin/sensor_config.conf \
--cmd-rx-ip <cmd-rx-ip> --cmd-rx-port 12345

Forklift safety function without PCM, on the host, where <nvpss-conf> is a copy of nvpss.conf with required_perception_monitor = 0:

sudo /opt/nvidia/psf/bin/launch_hoisa.sh --saim-mode active --pcm-mode skip --runtime host --app atl \
--nvpss-conf <nvpss-conf> \
--sensor-config /opt/nvidia/psf/bin/sensor_config.conf \
--sdm-config /opt/nvidia/psf/bin/atl_sdm_zone1.conf \
--cmd-rx-ip <cmd-rx-ip> --cmd-rx-port 12345

<cmd-rx-ip> is the address of the host running the command receiver. The configuration files named here are copies of the .sample templates.

Container options

The Safety Core image runs tini, then an entrypoint that starts cron and rsyslog as root, then runs /opt/nvidia/psf/bin/launch_psf.sh as the container user nvidia with the arguments given to docker run.

Container environment

VariableEffect
PCM_BASELINE_CONFIGIts directory part replaces the default of --pcm-baseline-dir.
PCM_MONITOR_CONFIGReplaces the default of --pcm-config.

Every process in the container runs as the container user nvidia, with that user’s primary group. Its group ID is set when the image is built; read it with docker run --rm --entrypoint id nvcr.io/nvidia/halos-outside-in/outside-in-safety:nv-psf-halos-1.4-6b92731 -g nvidia. A Safety Core process on the host that connects to the container (fsicom-agent with --sdm-on-fsi, or the SDMs with --sdm-external) must run with that group ID as its primary group, for example sudo setpriv --regid <gid> --keep-groups -- <command>, and the container must mount the host’s /run/nvpsf with -v /run/nvpsf:/run/nvpsf. See Shared process group.

Options

OptionDefaultValues and effect
--saim-mode <learn|active|skip>none, requiredSAIM’s mode, as for launch_hoisa.sh; see Monitor modes. Missing or invalid: Error: --saim-mode is required and must be learn, active, or skip.
--pcm-mode <learn|active|skip>none, requiredPCM’s mode. Missing or invalid: Error: --pcm-mode is required and must be learn, active, or skip.
--skip-pcmoffDeprecated alias for --pcm-mode skip, with the same warning and conflict error as launch_hoisa.sh.
--app <value>noneRequired in a control-plane run: Error: --app parameter is required. atl, pxc, atl,pxc, pxc,atl, atl,atl, atl_dual, pxc,pxc, or atl_proximity. See Container applications. In a learning run it only selects the default event mapping for PCM.
--sensor-config <file>noneRequired in a control-plane run and whenever SAIM is not skipped. The camera list, as a path inside the container. It must be readable: Error: sensor config file '<file>' not found or not readable.
--sdm-config <file[,file]>noneOne SDM configuration per SDM, as container paths of read-only mounts. Required when the SDMs run in the container. With --sdm-external, accepted only when PCM is not skipped, and given to PCM only. Not accepted with --sdm-on-fsi: Error: SDM configs must be supplied to the launcher that starts the SDMs. In a learning run, given to PCM, which then needs --app or --event-mapping: Error: PCM SDM configs require --app or --event-mapping.
--sdm-log-file <file[,file]><app>_sdm.log per SDMOne log file per SDM. A relative path is placed under /var/log/psf.
--event-mapping <file>the application’s shipped mappingOverrides the MDX client event mapping. PCM reads the same mapping. In a learning run, given to PCM: Error: PCM event mapping '<file>' is not readable if it cannot be read.
--atl-zone1-conf <file>, --atl-zone2-conf <file>noneOlder form of --sdm-config for ATL SDMs. --atl-zone1-conf is required for --app atl_proximity.
--cmd_rx_ip <ip>the SDM default, 127.0.0.1Command receiver address, passed to every SDM.
--cmd_rx_port <port[,port]>12345 for a single SDMOne port per SDM. For atl_proximity, the ATL SDM’s port.
--zone2_cmd_rx_port <port>noneOlder form of the second ATL port, for atl_dual or atl,atl.
--proximity_cmd_rx_port <port>12346atl_proximity only: the port of atl_proximity_sdm. Must differ from the ATL SDM’s port.
--pair_ttl_ms <ms>the SDM defaultatl_proximity only: passed to atl_proximity_sdm.
--sdm-externaloffStart the control plane and the monitors only. The SDMs run outside the container, as launch_hoisa.sh runs them, and must run with the container user’s primary group, through a mounted /run/nvpsf (see Container environment). ATL and Proximity applications only.
--sdm-on-fsioffStart the control plane and the monitors only; the SDM runs on the FSI and fsicom-agent must run on the host, with the container user’s primary group, through a mounted /run/nvpsf. A single atl or pxc SDM only. Cannot be combined with --sdm-external. See SDM on FSI.
--broker <host:port>localhost:9092Kafka broker for the MDX client (as --broker) and PCM (as --kafka-broker). Without it, the MDX client uses MDX_MSGBUS_BROKERS when that is set in the container, and PCM always uses localhost:9092, so use --broker rather than the variable.
--hb_stale_ms <ms>, --hb_period_ms <ms>5000, 5500Gateway heartbeat timing of the SDMs started in the container. Integers 100–600000.
--baseline-dir <dir>/opt/nvidia/psf/bin/saim_baselineSAIM’s working directory. It must exist. For active it must hold at least one baseline or template. For learn the entrypoint makes it owned by nvidia and stops if it is still not writable: Error: SAIM baseline folder '<dir>' is not writable for LEARN.
--pcm-baseline-dir <dir>/opt/nvidia/psf/bin/pcm_baselinePCM’s baseline directory. It must be readable: Error: PCM baseline folder '<dir>' is not readable (bind-mount it or pass --pcm-baseline-dir). For learn the entrypoint makes a dedicated directory owned by its user and stops if it is still not writable: Error: PCM baseline folder '<dir>' is not writable for LEARN.
--pcm-config <file>/opt/nvidia/psf/bin/pcm_monitor.cfgPCM’s monitor configuration, read when PCM is active. It must be readable: Error: PCM config '<file>' not found or not readable.
--learn-duration <seconds>300How long each learning monitor records. Integer 1–3600.
--gpu <id>nonePassed to SAIM as --gpu, and also exported as CUDA_VISIBLE_DEVICES. Only 0 works; see Known Limitations.
-h, --help—Prints the usage text and exits with status 0.

An unknown option prints Error: Unknown option '<option>' and the usage text, and the container exits with status 1. The container has no --mode option.

The entrypoint has no option for these files. Mount your own copy over the path in the image:

FilePath in the container
SEI configuration/opt/nvidia/psf/bin/nvpss.conf
SAIM thresholds/opt/nvidia/psf/bin/thresholds.cfg
Reviewed sensor set/opt/nvidia/psf/bin/sensor_pipelines_config.conf
3D sensor group fileThe path named by sensorGroupConfig in nvpss.conf

Container applications

In a control-plane run the entrypoint reads deploymentMode from /opt/nvidia/psf/bin/nvpss.conf and checks required_safety_monitor and required_perception_monitor against the monitor modes, as described in Monitor modes, before it starts anything. In 3D it checks that /opt/nvidia/psf/bin/sensor_pipelines_config.conf is readable. A learning run reads neither file and starts only the learning monitors.

--appProcesses, in start order
atl, pxc, atl,pxc, pxc,atl, atl,atl, atl_dual, pxc,pxcnvpss_daemon, nvpsd_gateway, the SDMs (unless --sdm-external or --sdm-on-fsi), mdx_client, then SAIM and PCM unless skipped
atl_proximitynvpsd_gateway, nvpss_daemon, atl_sdm (with --atl-zone1-conf), atl_proximity_sdm, mdx_client with /opt/nvidia/psf/apps/atl_proximity/event_mapping_atl_proximity.pb.txt, then SAIM and PCM unless skipped. No FSI variant: --sdm-on-fsi is refused.

The SDMs started in the container get --decision_interval_ms 0. The MDX client is started as instance 1, with --sensor-config in 2D or with --sensor-pipelines-config /opt/nvidia/psf/bin/sensor_pipelines_config.conf in 3D.

PCM is started with --baseline-config <pcm-baseline-dir>/pcm_baseline.cfg, with --kafka-broker when --broker is given, and, for the ATL and Proximity applications and in a learning run that has them, with the event mapping and each SDM configuration. A PCM in active reaches the host’s Docker daemon through /var/run/docker.sock when it is mounted. The switch to the nvidia user drops the groups that docker run --group-add adds, so when that user cannot read and write the socket, the entrypoint starts PCM with the socket’s group added (sudo -n setpriv ... --groups <groups>,<socket gid>). Without the socket mount, PCM’s container check stays off and PCM logs Docker socket unreachable; container health is NOT checked until Docker answers again.

The entrypoint supervises what it started. If a control-plane process exits, or a monitor fails as described in Supervision, shutdown and exit status, it stops the others (SIGTERM, then SIGKILL after 10 s) and the container exits with status 1. In a learning run it prints All selected monitors completed LEARN successfully and exits with status 0 when every learning monitor succeeded.

Inside the container, SAIM output goes to /var/log/psf/saim.log and PCM output to /var/log/psf/pcm.log, and both also to the container output. The SDMs started in the container write their own logs to /var/log/psf/<app>_sdm.log. The syslog records of the SEI daemon, the NvPSD Gateway and the MDX client go to /var/log/psf/psf.log. Everything also appears in docker logs <container>.

Plain docker run examples

Forklift safety function with the SDM, SAIM, PCM and the control plane in the container, on x86-64. Every Safety Core process then runs with the container user’s group, so the container needs no /run/nvpsf mount:

docker run -d --name nv-psf --network=host --gpus all \
-e NVIDIA_DRIVER_CAPABILITIES=compute,utility,video \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /opt/nvidia/psf/bin/sensor_config.conf:/opt/nvidia/psf/bin/sensor_config.conf:ro \
-v /opt/nvidia/psf/bin/nvpss.conf:/opt/nvidia/psf/bin/nvpss.conf:ro \
-v /opt/nvidia/psf/bin/atl_sdm_zone1.conf:/opt/nvidia/psf/bin/atl_sdm_zone1.conf:ro \
-v /opt/nvidia/psf/bin/pcm_monitor.cfg:/opt/nvidia/psf/bin/pcm_monitor.cfg:ro \
-v /opt/nvidia/psf/bin/saim_baseline:/opt/nvidia/psf/bin/saim_baseline:ro \
-v /opt/nvidia/psf/bin/pcm_baseline:/opt/nvidia/psf/bin/pcm_baseline:ro \
nvcr.io/nvidia/halos-outside-in/outside-in-safety:nv-psf-halos-1.4-6b92731 \
--app atl --saim-mode active --pcm-mode active \
--sensor-config /opt/nvidia/psf/bin/sensor_config.conf \
--sdm-config /opt/nvidia/psf/bin/atl_sdm_zone1.conf \
--cmd_rx_ip <cmd-rx-ip> --cmd_rx_port 12345

The PCM baselines in the mounted directory must have been learned with the same --app and --sdm-config. To learn them with the container, run it in the foreground; it exits when both monitors have finished:

docker run --rm --name nv-psf-learn --network=host --gpus all \
-e NVIDIA_DRIVER_CAPABILITIES=compute,utility,video \
-v /opt/nvidia/psf/bin/sensor_config.conf:/opt/nvidia/psf/bin/sensor_config.conf:ro \
-v /opt/nvidia/psf/bin/atl_sdm_zone1.conf:/opt/nvidia/psf/bin/atl_sdm_zone1.conf:ro \
-v /opt/nvidia/psf/bin/saim_baseline:/opt/nvidia/psf/bin/saim_baseline \
-v /opt/nvidia/psf/bin/pcm_baseline:/opt/nvidia/psf/bin/pcm_baseline \
nvcr.io/nvidia/halos-outside-in/outside-in-safety:nv-psf-halos-1.4-6b92731 \
--saim-mode learn --pcm-mode learn --learn-duration 300 --app atl \
--sensor-config /opt/nvidia/psf/bin/sensor_config.conf \
--sdm-config /opt/nvidia/psf/bin/atl_sdm_zone1.conf

On aarch64, replace --gpus all with --runtime nvidia -e NVIDIA_VISIBLE_DEVICES=all. The entrypoint gives SAIM the groups of the GPU and PVA device nodes itself, so --group-add is not needed. Add --broker <host:port> to either command when Kafka is not at localhost:9092. Follow the output with docker logs -f nv-psf. The mounted nvpss.conf must require the monitors that run, as described in Monitor modes.

Logs on the host. Without a log mount the logs stay in the container and are lost when it is removed. To keep them, add -v /var/log/psf:/var/log/psf, and first create on the host every log file the container writes, with mode 666: psf.log, saim.log and pcm.log, and each SDM log (see Applications). The container user can write to those files but cannot create files in the host directory; a missing file stops the container with Error: monitor log is not writable: /var/log/psf/<saim|pcm>.log or Error: cannot create SDM log '<file>'. Quick Deployment uses this mount.

A process on the host. With --sdm-on-fsi or --sdm-external, add -v /run/nvpsf:/run/nvpsf and start the process on the host as described in Container environment. The procedures are in Decision maker on the host and SDM on FSI.

fsicom-agent

fsicom-agent runs on the CCPLEX when the SDM runs on the Functional Safety Island. It connects to the NvPSD Gateway like an SDM, forwards each DecisionRequest to the FSI over the FSI communication channel, and relays the FSI SDM’s commands to the command receiver over UDP. It is installed by the psf-tegra-fsi package at /opt/nvidia/psf/bin/fsicom-agent, and must run as root with the nvFsiCom daemon already running.

sudo /opt/nvidia/psf/bin/fsicom-agent --heartbeat --relay-fsi-resp \
--ip <cmd-rx-ip> --port <cmd-rx-port> --cmd-identifier <0xA2|0xA5>

fsicom-agent accepts both --option value and --option=value.

OptionDefaultValues and effect
--relay-fsi-respoffRelay the commands that the FSI SDM sends back to the command receiver over UDP, and forward the receiver’s safe-release requests to the FSI. Requires --ip, --port and --cmd-identifier: [ERROR] --relay-fsi-resp requires --ip option, [ERROR] --relay-fsi-resp requires --port option, or [ERROR] --cmd-identifier is required with --relay-fsi-resp (wire identifier of the app being served).
--ip <IPv4>noneAddress of the command receiver. Otherwise [ERROR] Invalid IP address: <value>. Without --relay-fsi-resp it only produces a warning.
--port <port>noneThe command receiver’s listen port (its -p), 1–65535. Otherwise [ERROR] Invalid port number: <value> (must be 1-65535).
--cmd-identifier <byte>noneThe packet identifier of the application on the FSI, 1–255. Decimal, hexadecimal (0xA2) and octal are accepted. Use 0xA2 for the forklift safety function and 0xA5 for Proximity Monitoring. The agent stamps it on every relayed command and requires it on safe-release requests.
--heartbeatoffSend heartbeat pings to the FSI and track its keepalives and pongs. If no FSI keepalive arrives for more than 3 s, the agent logs [HB] WARNING: No FSI keepalive for <s> s.
--heartbeat-interval <ms>2000Ping interval, 100–60000. Otherwise [ERROR] Invalid heartbeat interval: <value> (must be 100-60000 ms). No effect without --heartbeat.
--debugoffPrint every packet.
-h, --help—Prints the usage text and exits with status 0.

--gw-transport, --gw-socket, --gw-ip and --gw-port are retired. Passing one prints an “unrecognized option” error and the usage text, and the agent exits with status 1. The link to the NvPSD Gateway is always /run/nvpsf/nvpsd_gateway.

Behaviour.

  • Gateway link. If the gateway is not up yet, the agent logs [GW] Awaiting NvPSDGateway (UNIX_SOCKET)... and retries every 500 ms without limit, so it can start before or after the Safety Core. It registers for EVENT_0 to EVENT_23 and SW_FAIL, and re-registers every 30 s. A refusal is logged once per reason: [GW] The gateway refused this agent's registration; reason=<reason> -- not registered, no decisions will reach the FSI SDM.
  • Gateway heartbeat. If no gateway heartbeat arrives for 8 s, the agent logs [GW-WD] PSDGateway heartbeat lost for <ms> ms. It takes no other action; the FSI SDM detects the loss through its own decision-freshness check.
  • Command receiver. With --relay-fsi-resp, the agent sends a heartbeat command to the receiver every 5 s. It forwards a safe-release request to the FSI only when the request comes from the exact --ip and --port, carries the --cmd-identifier, and has a valid CRC, and at most once per second.
  • Socket buffers. The agent’s gateway socket needs net.core.rmem_max and net.core.wmem_max of at least 5283840 bytes. While they are lower, every connection attempt fails with nvpsf_transport: SO_RCVBUF granted <n> bytes but <m> are required ...; raise net.core.rmem_max, and the agent keeps retrying.
  • FSI channel. The device tree must have the nvidia,tegra-fsicom-bufdemo-10k node with channelid_list = <6>; otherwise the agent stops with [ERROR] Reading channel configuration failed. If FSI communication cannot be initialised, the agent prints [ERROR] FSI COM initialization failed: <code> with hints and stops. When nvFsiCom is not running, the agent does not get past [INIT] Initializing FSI communication....

A healthy start prints these lines, in order:

[INIT] ✓ FSI communication initialized
[TRANSPORT] gateway upstream: UNIX_SOCKET
[GW] Connected to gateway 127.0.0.1:50000 — link established (first packet received)
[HB] First keepalive received (seq=<n>) — FSI heartbeat link up
[HB] First pong received (seq=<n>) — FSI responding to pings

The address in the [GW] Connected to gateway line is a leftover and is not used: the link is the local socket.

The agent logs to stdout and stderr only. launch_hoisa.sh appends both to the first SDM log (atl_sdm.log or pxc_sdm.log). The SDM on the FSI logs to the FSI UART; use the tcu_muxer utility to find its device node.

Binary command lines

All binaries except fsicom-agent take options only in the form --option value: --option=value is rejected as an unknown option. Each binary prints its usage text with -h or --help, except safety_monitor, which has no help option.

BinaryInstalled at
nvpss_daemon, nvpsd_gateway, safety_monitor, nv_perception_monitor/opt/nvidia/psf/bin/
mdx_client/opt/nvidia/psf/apps/mdx-client/
atl_sdm, atl_sdm_cmd_receiver/opt/nvidia/psf/apps/atl/
proximity_sdm, proximity_sdm_cmd_receiver/opt/nvidia/psf/apps/proximity/
atl_proximity_sdm, atl_proximity_sdm_cmd_receiver/opt/nvidia/psf/apps/atl_proximity/

nvpss_daemon (SEI)

OptionDefaultNotes
--conf <path>/opt/nvidia/psf/bin/nvpss.confEverything else comes from this file. See SEI Configuration.

Any other argument: error: unexpected argument (see --help), exit status 1.

nvpsd_gateway (NvPSD Gateway)

All options are optional. Both launchers start the gateway with none, so the defaults apply.

OptionDefaultRangeEffect
--num_clients <n>101–10Maximum number of registered SDMs (and fsicom-agent).
--max_hb_failures <n>101–255Missed SDM heartbeats before the gateway frees the SDM’s slot. The gateway uses the same limit for its own heartbeat to the SEI daemon.
--regr_max_per_window <n>41–64Registrations accepted from one connection per window.
--regr_window_ms <ms>100001000–600000Length of that window.

--transport, --sdm_socket, --sdm_ip, --sdm_port and --sdm_allow are retired: they get error: unknown option (see --help) and exit status 1. A missing or out-of-range value prints an error: line and exits with status 1. The gateway opens no TCP or UDP port; SDMs connect to /run/nvpsf/nvpsd_gateway. At startup it connects to the SEI daemon (60 attempts, 500 ms apart) and exits with status 1 if that fails.

mdx_client (MDX client)

OptionRequiredDefaultNotes
-c, --config <file>yesnoneThe event mapping. A first positional argument is also taken as the mapping. See Event Mapping Configuration.
-s, --sensor-config <file>one of -s or -gnone2D: the camera list, which maps Kafka sensor names to pipelineId.
-g, --sensor-pipelines-config <file>one of -s or -gnone3D: the reviewed sensor set, which maps the BEV group name to its pipelineId.
-i, --instance-id <n>nonone (anonymous)1–8. The instance number the SEI daemon tracks and that required_mdx_instances refers to. The launchers pass 1.
-b, --broker <host:port>noMDX_MSGBUS_BROKERS, else localhost:9092Kafka broker.
-d, --debugnooffPrint matched events instead of reporting them. The client does not register with the SEI daemon in this mode.

Giving both -s and -g prints error: -s/--sensor-config and -g/--sensor-pipelines-config are mutually exclusive; supply exactly one. Giving neither prints error: a sensor identity file is required: -s/--sensor-config for 2D, or -g/--sensor-pipelines-config for 3D/BEV. Both exit with status 1. The client logs to syslog with the tag nv_mdx_client. If 10 consecutive heartbeats to the SEI daemon fail (about 50 s), it logs PSS heartbeat ACK failure limit reached — PSS presumed dead, exiting and exits.

atl_sdm (forklift safety function)

OptionRequiredDefaultRange
--config <file>yesnoneThe event binding: six keys, forklift_entered, forklift_exited, person_entered, person_exited, roi_violation and roi_cleared, each set to a distinct EVENT_0–EVENT_23. See the atl_sdm_zone1.conf.sample template.
--cmd_rx_ip <ip>no127.0.0.1IPv4 address of the command receiver
--cmd_rx_port <port>no123451–65535
--log_file <path>noatl_sdm.log in the working directoryOne per SDM when several run together
--sensor_pipelines_config <file>no/opt/nvidia/psf/bin/sensor_pipelines_config.confThe file itself is mandatory: a missing or malformed file stops the SDM.
--max_hb_failures <n>no101–255. NvPSD Gateway heartbeat misses before the latch.
--hb_stale_ms <ms>no5000100–600000. Time without a gateway heartbeat before the first miss.
--hb_period_ms <ms>no5500100–600000. Time per further miss.
--decision_freshness_timeout_ms <ms>no700050–300000. Time without an accepted DecisionRequest before the SDM latches.
--decision_interval_ms <ms>no50000 (off) or 100–36000. The launchers pass 0.

The --config file is validated strictly: a missing, repeated, unknown or invalid key stops the SDM with error: --config <path>: <reason>. A safety_pipelines line from an earlier release is rejected by name; the reviewed sensor set comes from --sensor_pipelines_config. --events is retired and rejected by name. --gateway_ip and --gateway_port are not accepted (error: unknown option (see --help)). Command-line errors exit with status 1; a startup failure after parsing (for example an unloadable reviewed sensor set) exits with status 255.

proximity_sdm (Proximity Monitoring)

proximity_sdm takes the same options as atl_sdm, with these differences:

OptionDefaultNotes
--config <file>none, requiredThe pair groups to monitor and their event codes: optional pair_groups = <group>[,<group>], then <group>_normal, <group>_reduce and <group>_stop for each selected group. Groups: forklift_person, humanoid_person, transporter_person, fourier_humanoid_person. Without pair_groups, the first three are selected. See the pxc_sdm_forklift.conf.sample and pxc_sdm_robots.conf.sample templates.
--log_file <path>pxc_sdm.log in the working directory
--halo_ip <ip>none (off)Also send every decision command to a VST halo-overlay listener. Setting it alone enables the halo on the default port.
--halo_port <port>12346No effect without --halo_ip.
--gateway_ip <ip>, --gateway_port <port>127.0.0.1, 50000Still accepted, with no effect.

atl_proximity_sdm (forklift safety function with forklift–person proximity)

Started only by the container entrypoint with --app atl_proximity, next to an atl_sdm. It takes no --config, --log_file or instance option, and always logs to atl_proximity_sdm.log in its working directory.

OptionDefaultNotes
--cmd_rx_ip <ip>127.0.0.1
--cmd_rx_port <port>12346Must differ from the atl_sdm port.
--pair_ttl_ms <ms>2000200–60000. How long a forklift–person pair is kept without a new observation.
--sensor_pipelines_config <file>, --max_hb_failures, --hb_stale_ms, --hb_period_ms, --decision_freshness_timeout_ms, --decision_interval_msas for atl_sdm
--gateway_ip <ip>, --gateway_port <port>127.0.0.1, 50000Still accepted, with no effect.

Command receivers

atl_sdm_cmd_receiver, proximity_sdm_cmd_receiver and atl_proximity_sdm_cmd_receiver are the reference PLC endpoints. They take the same options:

OptionDefaultRange and effect
-p <port>12345Local UDP listen port, 1–65535. Set it to the SDM’s --cmd_rx_port. For atl_proximity_sdm that is 12346, not the default.
--sdm_ip <ipv4>127.0.0.1Accept packets only from this sender address.
--sdm_port <port>anyAccept packets only from this sender port, 1–65535. The SDMs send from an ephemeral port, so leave it unset.
--max_hb_failures <n>101–255. Missed SDM heartbeats before the receiver stops (see below).
--vst_ip <ipv4>, --vst_port <port>offAlso relay each command packet to a VST display listener. Give both or neither: error: --vst_ip and --vst_port must be used together.
--log-file <path>/tmp/cmdrx.logVerbose per-packet log. The console shows only latch, clear and release events. Two receivers left on the default share one file.
--no-log-fileoffSend the verbose log to the console.
  • Heartbeat watchdog. The receiver counts a miss once 5 s pass without an SDM heartbeat, and one more every 5.5 s after that. At --max_hb_failures misses (about 54.5 s at 10) it prints cmd_rx: upstream CMD_HEARTBEAT fault latched (tier 3) — local fail-safe, no PSS — stopping and exits with status 0. The watchdog starts when the receiver starts, so a receiver whose SDM never comes up also stops.
  • Release on first contact. 500 ms after the first valid packet from the SDM, the receiver sends one safe-release request, logged as Startup: peer connected — sending safe-release to clear any pre-existing latch. The SDM still denies it while a fault is active.
  • Interactive release. After the SDM reports a latched safe state, typing release (or r, safe-release, y, yes) sends a safe-release request.
  • If the receiver cannot bind its port, it prints Error binding socket: <error> and exits with status 0.

safety_monitor (SAIM)

OptionRequiredDefaultNotes
--mode <LEARN|ACTIVE>noACTIVEUpper case only.
--sensor-config <file>yesnoneOne RTSP stream per row.
--threshold-config <file>nothresholds.cfg in the working directoryActive mode only. A missing or invalid file is not fatal: SAIM prints WARNING: threshold config <path> is missing or invalid; using built-in defaults.
--learn-duration <seconds>no3001–3600. Learn mode only.
--gpu <id>nostreams spread across the visible GPUsMust be below the number of visible GPUs: Error: --gpu <id> is out of range (0-<n>).

SAIM reads and writes its baselines as <sensorName>_baseline.cfg in its working directory; see Default baselines. The accelerator backend is fixed at build time: the GPU on x86-64, and the PVA in the shipped aarch64 build. SAIM tries to register with the SEI daemon 6 times, 5 s apart, then exits with Failed to register with PSS daemon after 6 attempts. Exiting. It logs to stdout and stderr only. An unknown argument prints Error: unknown argument: <argument>, and SAIM exits with status 1.

nv_perception_monitor (PCM)

OptionDefaultNotes
--mode <LEARN|ACTIVE>ACTIVEEither case. LEARN records a baseline and does not register with the SEI daemon.
--learn-duration <seconds>3001–3600. Learn mode only.
--baseline-config <file>$PCM_BASELINE_CONFIG, else /opt/nvidia/psf/bin/pcm_baseline/pcm_baseline.cfgOnly the directory part is used. LEARN writes pcm_baseline.cfg there; see PCM baselines.
--kafka-broker <host:port>localhost:9092Kafka broker for the mdx-frames topic.
--event-mapping <file>noneThe MDX event mapping whose rules PCM records (LEARN) or checks (ACTIVE). At most once.
--sdm-config <file>noneOne SDM configuration; repeat the option for each SDM. Selects which rules of the mapping apply. Needs --event-mapping.

In active mode PCM reads /opt/nvidia/psf/bin/pcm_monitor.cfg (or $PCM_MONITOR_CONFIG), whose [monitors] section enables container_health and data_validation. Both are on by default. PCM reaches Docker through /var/run/docker.sock. It registers with the SEI daemon in 6 attempts, 5 s apart, and exits if that fails. An argument error, an unusable pcm_monitor.cfg in active mode, or an event mapping or SDM configuration it cannot use exits with status 2. PCM logs to stdout and stderr only, as lines starting [<date> <time>] [PCM][INFO|WARNING|ERR]; both launchers copy both streams to /var/log/psf/pcm.log. The checks and the configuration keys are on Perception Monitor.