jurmy24's picture
refactor: rename URDF to Urdf
6bc7874
import { XMLParser } from "npm:[email protected]";
import { serve } from "https://deno.land/[email protected]/http/server.ts";
interface UrdfLink {
name: string;
mass: number;
inertia: {
ixx: number;
ixy: number;
ixz: number;
iyy: number;
iyz: number;
izz: number;
};
has_visual: boolean;
has_collision: boolean;
}
interface UrdfJoint {
name: string;
type: string;
parent: string;
child: string;
limits?: {
lower: number;
upper: number;
effort: number;
velocity: number;
};
}
const corsHeaders = {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Headers":
"authorization, x-client-info, apikey, content-type",
"Access-Control-Allow-Methods": "POST, OPTIONS",
};
serve(async (req) => {
// Handle CORS preflight requests
if (req.method === "OPTIONS") {
return new Response("ok", { headers: corsHeaders });
}
try {
if (req.method !== "POST") {
throw new Error("Method not allowed");
}
const { urdfContent } = await req.json();
if (!urdfContent) {
throw new Error("No Urdf content provided");
}
// Parse Urdf XML using fast-xml-parser
const parser = new XMLParser({
ignoreAttributes: false,
attributeNamePrefix: "",
parseAttributeValue: true,
});
const doc = parser.parse(urdfContent);
if (!doc || !doc.robot) {
throw new Error("No robot element found in Urdf");
}
// Extract robot data
const robotElement = doc.robot;
const name = robotElement.name || "unnamed_robot";
const version = robotElement.version;
const links: UrdfLink[] = [];
const joints: UrdfJoint[] = [];
let total_mass = 0;
// Parse links
if (robotElement.link) {
const linkElements = Array.isArray(robotElement.link)
? robotElement.link
: [robotElement.link];
linkElements.forEach((link: any) => {
const linkName = link.name || "";
const inertial = link.inertial;
const mass = inertial?.mass?.value || 0;
total_mass += mass;
const linkData: UrdfLink = {
name: linkName,
mass,
inertia: {
ixx: 0,
ixy: 0,
ixz: 0,
iyy: 0,
iyz: 0,
izz: 0,
},
has_visual: !!link.visual,
has_collision: !!link.collision,
};
// Parse inertia
if (inertial?.inertia) {
const inertiaEl = inertial.inertia;
linkData.inertia = {
ixx: inertiaEl.ixx || 0,
ixy: inertiaEl.ixy || 0,
ixz: inertiaEl.ixz || 0,
iyy: inertiaEl.iyy || 0,
iyz: inertiaEl.iyz || 0,
izz: inertiaEl.izz || 0,
};
}
links.push(linkData);
});
}
// Parse joints
if (robotElement.joint) {
const jointElements = Array.isArray(robotElement.joint)
? robotElement.joint
: [robotElement.joint];
jointElements.forEach((joint: any) => {
const jointData: UrdfJoint = {
name: joint.name || "",
type: joint.type || "",
parent: joint.parent?.link || "",
child: joint.child?.link || "",
};
// Parse limits
if (joint.limit) {
jointData.limits = {
lower: joint.limit.lower || 0,
upper: joint.limit.upper || 0,
effort: joint.limit.effort || 0,
velocity: joint.limit.velocity || 0,
};
}
joints.push(jointData);
});
}
const response = {
success: true,
data: {
name,
version,
links,
joints,
total_mass,
num_links: links.length,
num_joints: joints.length,
},
};
return new Response(JSON.stringify(response), {
headers: {
...corsHeaders,
"Content-Type": "application/json",
},
});
} catch (error) {
console.error("Error parsing Urdf:", error);
return new Response(
JSON.stringify({
success: false,
error:
error instanceof Error ? error.message : "Unknown error occurred",
}),
{
status: 500,
headers: {
...corsHeaders,
"Content-Type": "application/json",
},
}
);
}
});