This commit is contained in:
104
www/map-yaml.js
Normal file
104
www/map-yaml.js
Normal file
@@ -0,0 +1,104 @@
|
||||
(() => {
|
||||
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 };
|
||||
})();
|
||||
Reference in New Issue
Block a user