const roles = ['agent', 'vehicle', 'slam', 'map', 'localization', 'planning', 'control', 'camera'] as const export function yahboomSimulation(folderName: string | null | undefined, rosParams: string): boolean { return Boolean(yahboomRuntimeImage(folderName)) && !/yahboom-(agent|camera)\]/.test(folderName ?? '') && /(?:^|\s)sim_mode:=true(?:\s|$)/.test(rosParams) } type RuntimeArtifact = { image?: string | null url?: string | null fileName?: string | null checksumSha256?: string | null required?: boolean | null } const artifactRoot = 'https://pub-ca72c40797144462bdb7d200c215d361.r2.dev/studio-artifacts/runtime-images/nav2/yahboom/arm64' const artifacts: RuntimeArtifact[] = [ ['future-nav2:humble-yahboom', 'future-nav2-humble-yahboom.tar.zst', 'b2f168c45b961ab96badeeb7df68d1c997996c75dcb5e0cc677b0b6669b1ffd2'], ['future-nav2:humble-yahboom-agent', 'future-nav2-humble-yahboom-agent.tar.zst', 'e30404506c320af1d53c8733177eaf27997dcb2864019b8fcc6888874f02d191'], ].map(([image, fileName, checksumSha256]) => ({ image, fileName, checksumSha256, required: true, url: `${artifactRoot}/${checksumSha256.slice(0, 16)}/${fileName}`, })) export function yahboomRuntimeArtifacts( folderName: string, runtimeImage: string | null, configured?: RuntimeArtifact[] | null, ): RuntimeArtifact[] | null | undefined { if (!yahboomRuntimeImage(folderName)) return configured const selected = configured?.find((item) => item.image?.trim() === runtimeImage && item.url?.trim()) ?? artifacts.find((item) => item.image === runtimeImage) // Yahboom must not download unrelated Jetson images from an existing profile. return selected ? [selected] : [] } export function yahboomRuntimeImage(folderName?: string | null): string | null { const role = folderName?.match(/^\[lms-nav2-yahboom-([a-z]+)\]yahboom_\1_v[^/]+_ws$/)?.[1] if (!roles.some((value) => value === role)) return null return role === 'agent' ? 'future-nav2:humble-yahboom-agent' : 'future-nav2:humble-yahboom' } export function yahboomModuleCases(build = false): string[] { return roles.map((role) => ( ` "[lms-nav2-yahboom-${role}]yahboom_${role}_v"*_ws) ${build ? `TARGET=yahboom_${role}` : `PACKAGE=yahboom_${role}; LAUNCH=${role}.launch.py`} ;;` )) } // Keep hardware exposure limited to the two hardware-facing Yahboom templates. export function yahboomDevicePreflight(): string[] { return [ 'YAHBOOM_DEVICE=""', 'case "$MODULE_FOLDER" in', ' "[lms-nav2-yahboom-agent]yahboom_agent_v"*_ws)', ' YAHBOOM_DEVICE=/dev/ttyUSB0', ' for arg in "$@"; do case "$arg" in serial_device:=*) YAHBOOM_DEVICE=${arg#serial_device:=} ;; esac; done', ' case "$YAHBOOM_DEVICE" in /dev/ttyUSB*|/dev/ttyACM*|/dev/serial/by-id/*) ;; *) echo "Invalid Yahboom serial device" >&2; exit 64 ;; esac', ' ;;', ' "[lms-nav2-yahboom-camera]yahboom_camera_v"*_ws)', ' YAHBOOM_DEVICE=/dev/video0', ' for arg in "$@"; do case "$arg" in video_device:=*) YAHBOOM_DEVICE=${arg#video_device:=} ;; esac; done', ' [[ "$YAHBOOM_DEVICE" =~ ^/dev/video[0-9]+$ ]] || { echo "Invalid Yahboom camera device" >&2; exit 64; }', ' ;;', 'esac', 'if [ -n "$YAHBOOM_DEVICE" ]; then', ' [[ "$YAHBOOM_DEVICE" != *".."* ]] && [ -c "$YAHBOOM_DEVICE" ] || { echo "Yahboom device not found: $YAHBOOM_DEVICE" >&2; exit 1; }', 'fi', ] }