Files
App/www/map-yaml.js
HiepLM 819323f8c8
Some checks failed
Test / test (push) Has been cancelled
add function map viewer
2026-06-20 10:53:49 +07:00

105 lines
3.3 KiB
JavaScript

(() => {
function stripComment(line) {
const pos = line.indexOf("#");
return pos === -1 ? line : line.slice(0, pos);
}
function trim(s) {
return String(s || "").trim();
}
function parseOriginArray(value) {
const start = value.indexOf("[");
const end = value.indexOf("]");
if (start === -1 || end === -1 || end <= start) return null;
const parts = value
.slice(start + 1, end)
.split(",")
.map((p) => Number(trim(p)))
.filter((n) => !Number.isNaN(n));
if (parts.length < 2) return null;
return { origin_x: parts[0], origin_y: parts[1], origin_yaw: parts[2] || 0 };
}
function parseNumber(value) {
const n = Number(value);
return Number.isFinite(n) ? n : null;
}
function parseIntField(value) {
const n = parseInt(value, 10);
return Number.isFinite(n) ? n : null;
}
/**
* Parse ROS map_server yaml (resolution, origin, thresholds).
* @param {string} text
* @param {{ requireImage?: boolean }} opts
*/
function parse(text, opts = {}) {
const requireImage = !!opts.requireImage;
const out = {
image: "",
resolution: null,
origin_x: 0,
origin_y: 0,
origin_yaw: 0,
negate: 0,
occupied_thresh: 0.65,
free_thresh: 0.196,
};
for (const rawLine of String(text || "").split(/\r?\n/)) {
const line = trim(stripComment(rawLine));
if (!line) continue;
const colon = line.indexOf(":");
if (colon === -1) continue;
const key = trim(line.slice(0, colon));
const value = trim(line.slice(colon + 1));
if (!value && key !== "image") continue;
if (key === "image") out.image = value;
else if (key === "resolution") out.resolution = parseNumber(value);
else if (key === "origin") {
const origin = parseOriginArray(value);
if (origin) Object.assign(out, origin);
} else if (key === "negate") {
const n = parseIntField(value);
if (n != null) out.negate = n;
} else if (key === "occupied_thresh") {
const n = parseNumber(value);
if (n != null) out.occupied_thresh = n;
} else if (key === "free_thresh") {
const n = parseNumber(value);
if (n != null) out.free_thresh = n;
}
}
if (requireImage && !out.image) return { error: "yaml missing image field" };
if (out.resolution == null || out.resolution <= 0) return { error: "yaml missing resolution field" };
return out;
}
function serialize(meta) {
const image = meta.image || "map.png";
const resolution = meta.resolution != null ? meta.resolution : 0.05;
const ox = meta.origin_x != null ? meta.origin_x : 0;
const oy = meta.origin_y != null ? meta.origin_y : 0;
const oyaw = meta.origin_yaw != null ? meta.origin_yaw : 0;
const negate = meta.negate != null ? meta.negate : 0;
const occ = meta.occupied_thresh != null ? meta.occupied_thresh : 0.65;
const free = meta.free_thresh != null ? meta.free_thresh : 0.196;
return [
`image: ${image}`,
`resolution: ${Number(resolution).toFixed(6)}`,
`origin: [${Number(ox).toFixed(6)}, ${Number(oy).toFixed(6)}, ${Number(oyaw).toFixed(6)}]`,
`negate: ${negate}`,
`occupied_thresh: ${Number(occ).toFixed(3)}`,
`free_thresh: ${Number(free).toFixed(3)}`,
"",
].join("\n");
}
window.MapYaml = { parse, serialize };
})();