Adds yertle model visulization

This commit is contained in:
Rune Harlyk
2025-07-11 13:25:03 +02:00
committed by Rune Harlyk
parent 2eab893dd7
commit c5901c65b3
31 changed files with 212288 additions and 182 deletions
+165 -167
View File
@@ -1,5 +1,5 @@
<script lang="ts"> <script lang="ts">
import { onDestroy, onMount } from 'svelte'; import { onDestroy, onMount } from 'svelte'
import { import {
BufferGeometry, BufferGeometry,
Line, Line,
@@ -10,8 +10,8 @@
SphereGeometry, SphereGeometry,
Vector3, Vector3,
type NormalBufferAttributes, type NormalBufferAttributes,
type Object3DEventMap, type Object3DEventMap
} from 'three'; } from 'three'
import { import {
ModesEnum, ModesEnum,
kinematicData, kinematicData,
@@ -22,54 +22,55 @@
servoAngles, servoAngles,
mpu, mpu,
jointNames, jointNames,
} from '$lib/stores'; currentKinematic
} from '$lib/stores'
import { import {
extractFootColor, extractFootColor,
populateModelCache, populateModelCache,
throttler, throttler,
getToeWorldPositions, getToeWorldPositions
} from '$lib/utilities'; } from '$lib/utilities'
import SceneBuilder from '$lib/sceneBuilder'; import SceneBuilder from '$lib/sceneBuilder'
import { lerp, degToRad } from 'three/src/math/MathUtils'; import { lerp, degToRad } from 'three/src/math/MathUtils'
import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; import { GUI } from 'three/addons/libs/lil-gui.module.min.js'
import Kinematic, { type body_state_t } from '$lib/kinematic'; import Kinematic, { type body_state_t } from '$lib/kinematic'
import { import {
BezierState, BezierState,
CalibrationState, CalibrationState,
EightPhaseWalkState, EightPhaseWalkState,
IdleState, IdleState,
RestState, RestState,
StandState, StandState
} from '$lib/gait'; } from '$lib/gait'
import { radToDeg } from 'three/src/math/MathUtils.js'; import { radToDeg } from 'three/src/math/MathUtils.js'
import type { URDFRobot } from 'urdf-loader'; import type { URDFRobot } from 'urdf-loader'
import { get } from 'svelte/store'; import { get } from 'svelte/store'
interface Props { interface Props {
sky?: boolean; sky?: boolean
orbit?: boolean; orbit?: boolean
panel?: boolean; panel?: boolean
debug?: boolean; debug?: boolean
ground?: boolean; ground?: boolean
} }
let { sky = true, orbit = false, panel = true, debug = false, ground = true }: Props = $props(); let { sky = true, orbit = false, panel = true, debug = false, ground = true }: Props = $props()
let sceneManager = $state(new SceneBuilder()); let sceneManager = $state(new SceneBuilder())
let canvas: HTMLCanvasElement; let canvas: HTMLCanvasElement
let currentModelAngles: number[] = new Array(12).fill(0); let currentModelAngles: number[] = new Array(12).fill(0)
let modelTargetAngles: number[] = new Array(12).fill(0); let modelTargetAngles: number[] = new Array(12).fill(0)
let gui_panel: GUI; let gui_panel: GUI
let Throttler = new throttler(); let Throttler = new throttler()
let feet_trace = new Array(4).fill([]); let feet_trace = new Array(4).fill([])
let trace_lines: BufferGeometry<NormalBufferAttributes>[] = []; let trace_lines: BufferGeometry<NormalBufferAttributes>[] = []
let target: Object3D<Object3DEventMap>; let target: Object3D<Object3DEventMap>
let target_position = { x: 0, z: 0, yaw: 0 }; let target_position = { x: 0, z: 0, yaw: 0 }
let kinematic = new Kinematic(); let kinematic = get(currentKinematic)
let planners = { let planners = {
[ModesEnum.Deactivated]: new IdleState(), [ModesEnum.Deactivated]: new IdleState(),
@@ -78,11 +79,11 @@
[ModesEnum.Rest]: new RestState(), [ModesEnum.Rest]: new RestState(),
[ModesEnum.Stand]: new StandState(), [ModesEnum.Stand]: new StandState(),
[ModesEnum.Crawl]: new EightPhaseWalkState(), [ModesEnum.Crawl]: new EightPhaseWalkState(),
[ModesEnum.Walk]: new BezierState(), [ModesEnum.Walk]: new BezierState()
}; }
let lastTick = performance.now(); let lastTick = performance.now()
const dir = [1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1]; const dir = [1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1]
let body_state = { let body_state = {
omega: 0, omega: 0,
@@ -91,8 +92,8 @@
xm: 0, xm: 0,
ym: 0.5, ym: 0.5,
zm: 0, zm: 0,
feet: kinematic.getDefaultFeetPos(), feet: kinematic.getDefaultFeetPos()
}; }
let settings = { let settings = {
'Internal kinematic': true, 'Internal kinematic': true,
@@ -109,52 +110,52 @@
xm: 0, xm: 0,
ym: 0.7, ym: 0.7,
zm: 0, zm: 0,
Background: 'black', Background: 'black'
}; }
onMount(async () => { onMount(async () => {
await populateModelCache(); await populateModelCache()
await createScene(); await createScene()
servoAngles.subscribe(updateAnglesFromStore); servoAngles.subscribe(updateAnglesFromStore)
if (panel) createPanel(); if (panel) createPanel()
}); })
onDestroy(() => { onDestroy(() => {
canvas.remove(); canvas.remove()
gui_panel?.destroy(); gui_panel?.destroy()
}); })
const updateAnglesFromStore = (angles: number[]) => { const updateAnglesFromStore = (angles: number[]) => {
if (sceneManager.isDragging) return; if (sceneManager.isDragging) return
if (settings['Internal kinematic']) return; if (settings['Internal kinematic']) return
modelTargetAngles = angles; modelTargetAngles = angles
}; }
const createPanel = () => { const createPanel = () => {
gui_panel = new GUI({ width: 310 }); gui_panel = new GUI({ width: 310 })
gui_panel.close(); gui_panel.close()
gui_panel.domElement.id = 'three-gui-panel'; gui_panel.domElement.id = 'three-gui-panel'
const general = gui_panel.addFolder('General'); const general = gui_panel.addFolder('General')
general.add(settings, 'Internal kinematic'); general.add(settings, 'Internal kinematic')
general.add(settings, 'Robot transform controls'); general.add(settings, 'Robot transform controls')
general.add(settings, 'Auto orient robot'); general.add(settings, 'Auto orient robot')
const kinematic = gui_panel.addFolder('Kinematics'); const kinematic = gui_panel.addFolder('Kinematics')
kinematic.add(settings, 'omega', -20, 20).onChange(updateKinematicPosition).listen(); kinematic.add(settings, 'omega', -20, 20).onChange(updateKinematicPosition).listen()
kinematic.add(settings, 'phi', -30, 30).onChange(updateKinematicPosition).listen(); kinematic.add(settings, 'phi', -30, 30).onChange(updateKinematicPosition).listen()
kinematic.add(settings, 'psi', -20, 15).onChange(updateKinematicPosition).listen(); kinematic.add(settings, 'psi', -20, 15).onChange(updateKinematicPosition).listen()
kinematic.add(settings, 'xm', -1, 1).onChange(updateKinematicPosition).listen(); kinematic.add(settings, 'xm', -1, 1).onChange(updateKinematicPosition).listen()
kinematic.add(settings, 'ym', 0, 1).onChange(updateKinematicPosition).listen(); kinematic.add(settings, 'ym', 0, 1).onChange(updateKinematicPosition).listen()
kinematic.add(settings, 'zm', -1.3, 1.3).onChange(updateKinematicPosition).listen(); kinematic.add(settings, 'zm', -1.3, 1.3).onChange(updateKinematicPosition).listen()
const visibility = gui_panel.addFolder('Visualization'); const visibility = gui_panel.addFolder('Visualization')
visibility.add(settings, 'Trace feet'); visibility.add(settings, 'Trace feet')
visibility.add(settings, 'Trace points', 1, 1000, 1); visibility.add(settings, 'Trace points', 1, 1000, 1)
visibility.add(settings, 'Target position'); visibility.add(settings, 'Target position')
visibility.add(settings, 'Smooth motion'); visibility.add(settings, 'Smooth motion')
visibility.addColor(settings, 'Background'); visibility.addColor(settings, 'Background')
}; }
const updateKinematicPosition = () => { const updateKinematicPosition = () => {
kinematicData.set([ kinematicData.set([
@@ -163,17 +164,14 @@
settings.psi, settings.psi,
settings.xm, settings.xm,
settings.ym, settings.ym,
settings.zm, settings.zm
]); ])
}; }
const updateAngles = (name: string, angle: number) => { const updateAngles = (name: string, angle: number) => {
modelTargetAngles[$jointNames.indexOf(name)] = angle * (180 / Math.PI); modelTargetAngles[$jointNames.indexOf(name)] = angle * (180 / Math.PI)
Throttler.throttle( Throttler.throttle(() => servoAnglesOut.set(modelTargetAngles.map(num => Math.round(num))), 100)
() => servoAnglesOut.set(modelTargetAngles.map(num => Math.round(num))), }
100
);
};
const createScene = async () => { const createScene = async () => {
sceneManager sceneManager
@@ -187,46 +185,46 @@
.addTransformControls(sceneManager.model) .addTransformControls(sceneManager.model)
.fillParent() .fillParent()
.addRenderCb(render) .addRenderCb(render)
.startRenderLoop(); .startRenderLoop()
if (ground) sceneManager.addGroundPlane(); if (ground) sceneManager.addGroundPlane()
const geometry = new SphereGeometry(0.1, 32, 16); const geometry = new SphereGeometry(0.1, 32, 16)
const material = new MeshBasicMaterial({ color: 0xffff00 }); const material = new MeshBasicMaterial({ color: 0xffff00 })
target = new Mesh(geometry, material); target = new Mesh(geometry, material)
sceneManager.scene.add(target); sceneManager.scene.add(target)
if (debug) { if (debug) {
sceneManager.addDragControl(updateAngles); sceneManager.addDragControl(updateAngles)
} }
if (sky) sceneManager.addSky(); if (sky) sceneManager.addSky()
for (let i = 0; i < 4; i++) { for (let i = 0; i < 4; i++) {
const geometry = new BufferGeometry(); const geometry = new BufferGeometry()
const material = new LineBasicMaterial({ color: extractFootColor() }); const material = new LineBasicMaterial({ color: extractFootColor() })
const line = new Line(geometry, material); const line = new Line(geometry, material)
trace_lines.push(geometry); trace_lines.push(geometry)
sceneManager.scene.add(line); sceneManager.scene.add(line)
} }
}; }
const renderTraceLines = (foot_positions: Vector3[]) => { const renderTraceLines = (foot_positions: Vector3[]) => {
if (!settings['Trace feet']) { if (!settings['Trace feet']) {
if (!feet_trace.length) return; if (!feet_trace.length) return
trace_lines.forEach((line, i) => line.setFromPoints(feet_trace[i].slice(-1))); trace_lines.forEach((line, i) => line.setFromPoints(feet_trace[i].slice(-1)))
feet_trace = new Array(4).fill([]); feet_trace = new Array(4).fill([])
return; return
} }
trace_lines.forEach((line, i) => { trace_lines.forEach((line, i) => {
feet_trace[i].push(foot_positions[i]); feet_trace[i].push(foot_positions[i])
feet_trace[i] = feet_trace[i].slice(-settings['Trace points']); feet_trace[i] = feet_trace[i].slice(-settings['Trace points'])
line.setFromPoints(feet_trace[i]); line.setFromPoints(feet_trace[i])
}); })
}; }
const calculate_kinematics = () => { const calculate_kinematics = () => {
if (sceneManager.isDragging || !settings['Internal kinematic']) return; if (sceneManager.isDragging || !settings['Internal kinematic']) return
const position: body_state_t = { const position: body_state_t = {
omega: settings.omega, omega: settings.omega,
phi: settings.phi, phi: settings.phi,
@@ -234,37 +232,37 @@
xm: settings.xm, xm: settings.xm,
ym: settings.ym, ym: settings.ym,
zm: settings.zm, zm: settings.zm,
feet: body_state.feet, feet: body_state.feet
}; }
let new_angles = kinematic.calcIK(position).map((x, i) => radToDeg(x * dir[i])); let new_angles = kinematic.calcIK(position).map((x, i) => radToDeg(x * dir[i]))
modelTargetAngles = new_angles; modelTargetAngles = new_angles
}; }
const orient_robot = (robot: URDFRobot, toes: Vector3[]) => { const orient_robot = (robot: URDFRobot, toes: Vector3[]) => {
if (settings['Robot transform controls'] || !settings['Auto orient robot']) return; if (settings['Robot transform controls'] || !settings['Auto orient robot']) return
robot.position.y = robot.position.y - Math.min(...toes.map(toe => toe.y)); robot.position.y = robot.position.y - Math.min(...toes.map(toe => toe.y))
robot.position.z = smooth(robot.position.z, -settings.xm, 0.1); robot.position.z = smooth(robot.position.z, -settings.xm, 0.1)
robot.position.x = smooth(robot.position.x, -settings.zm, 0.1); robot.position.x = smooth(robot.position.x, -settings.zm, 0.1)
robot.rotation.z = smooth(robot.rotation.z, degToRad(-settings.phi + $mpu.heading + 90), 0.1); robot.rotation.z = smooth(robot.rotation.z, degToRad(-settings.phi + $mpu.heading + 90), 0.1)
robot.rotation.y = smooth(robot.rotation.y, degToRad(settings.omega), 0.1); robot.rotation.y = smooth(robot.rotation.y, degToRad(settings.omega), 0.1)
robot.rotation.x = smooth(robot.rotation.x, degToRad(settings.psi - 90), 0.1); robot.rotation.x = smooth(robot.rotation.x, degToRad(settings.psi - 90), 0.1)
}; }
const update_camera = (robot: URDFRobot) => { const update_camera = (robot: URDFRobot) => {
if (!settings['Fix camera on robot']) return; if (!settings['Fix camera on robot']) return
sceneManager.orbit.target = robot.position.clone(); sceneManager.orbit.target = robot.position.clone()
}; }
const smooth = (start: number, end: number, amount: number) => { const smooth = (start: number, end: number, amount: number) => {
return settings['Smooth motion'] ? lerp(start, end, amount) : end; return settings['Smooth motion'] ? lerp(start, end, amount) : end
}; }
const update_gait = () => { const update_gait = () => {
if (sceneManager.isDragging || !settings['Internal kinematic']) return; if (sceneManager.isDragging || !settings['Internal kinematic']) return
const controlData = get(outControllerData); const controlData = get(outControllerData)
const data = { const data = {
stop: controlData[0], stop: controlData[0],
lx: controlData[1], lx: controlData[1],
@@ -273,67 +271,67 @@
ry: controlData[4], ry: controlData[4],
h: controlData[5], h: controlData[5],
s: controlData[6], s: controlData[6],
s1: controlData[7], s1: controlData[7]
}; }
body_state.ym = ((data.h + 127) * 0.35) / 100; body_state.ym = ((data.h + 127) * 0.35) / 100
let planner = planners[get(mode)]; let planner = planners[get(mode)]
const delta = performance.now() - lastTick; const delta = performance.now() - lastTick
lastTick = performance.now(); lastTick = performance.now()
body_state = planner.step(body_state, data, delta); body_state = planner.step(body_state, data, delta)
settings.omega = body_state.omega; settings.omega = body_state.omega
settings.phi = body_state.phi; settings.phi = body_state.phi
settings.psi = body_state.psi; settings.psi = body_state.psi
settings.xm = body_state.xm; settings.xm = body_state.xm
settings.ym = body_state.ym; settings.ym = body_state.ym
settings.zm = body_state.zm; settings.zm = body_state.zm
}; }
const update_robot_position = (robot: URDFRobot) => { const update_robot_position = (robot: URDFRobot) => {
if (!settings['Robot transform controls']) return; if (!settings['Robot transform controls']) return
settings.omega = radToDeg(robot.rotation.y); settings.omega = radToDeg(robot.rotation.y)
settings.phi = radToDeg(robot.rotation.z) + $mpu.heading - 90; settings.phi = radToDeg(robot.rotation.z) + $mpu.heading - 90
settings.psi = radToDeg(robot.rotation.x) + 90; settings.psi = radToDeg(robot.rotation.x) + 90
settings.xm = robot.position.z * 100; settings.xm = robot.position.z * 100
settings.zm = -robot.position.x * 100; settings.zm = -robot.position.x * 100
}; }
const updateTargetPosition = () => { const updateTargetPosition = () => {
target.visible = settings['Target position']; target.visible = settings['Target position']
target.position.x = smooth(target.position.x, target_position.x, 0.5); target.position.x = smooth(target.position.x, target_position.x, 0.5)
target.position.z = smooth(target.position.z, target_position.z, 0.5); target.position.z = smooth(target.position.z, target_position.z, 0.5)
}; }
const render = () => { const render = () => {
const robot = sceneManager.model; const robot = sceneManager.model
if (!robot) return; if (!robot) return
const toes = getToeWorldPositions(robot); const toes = getToeWorldPositions(robot)
renderTraceLines(toes); renderTraceLines(toes)
update_camera(robot); update_camera(robot)
update_gait(); update_gait()
calculate_kinematics(); calculate_kinematics()
update_robot_position(robot); update_robot_position(robot)
sceneManager.transformControl.showX = settings['Robot transform controls']; sceneManager.transformControl.showX = settings['Robot transform controls']
sceneManager.transformControl.showY = settings['Robot transform controls']; sceneManager.transformControl.showY = settings['Robot transform controls']
sceneManager.transformControl.showZ = settings['Robot transform controls']; sceneManager.transformControl.showZ = settings['Robot transform controls']
for (let i = 0; i < $jointNames.length; i++) { for (let i = 0; i < $jointNames.length; i++) {
currentModelAngles[i] = smooth( currentModelAngles[i] = smooth(
(robot.joints[$jointNames[i]].angle as number) * (180 / Math.PI), (robot.joints[$jointNames[i]].angle as number) * (180 / Math.PI),
modelTargetAngles[i], modelTargetAngles[i],
0.1 0.1
); )
robot.joints[$jointNames[i]].setJointValue(degToRad(currentModelAngles[i])); robot.joints[$jointNames[i]].setJointValue(degToRad(currentModelAngles[i]))
} }
orient_robot(robot, toes); orient_robot(robot, toes)
updateTargetPosition(); updateTargetPosition()
}; }
</script> </script>
<svelte:window onresize={sceneManager.fillParent} /> <svelte:window onresize={sceneManager.fillParent} />
+3 -3
View File
@@ -1,6 +1,6 @@
import { get } from 'svelte/store'
import type { body_state_t } from './kinematic' import type { body_state_t } from './kinematic'
import Kinematic from './kinematic' import { currentKinematic } from './stores/featureFlags'
import { fromInt8 } from './utilities'
const { sin } = Math const { sin } = Math
@@ -39,7 +39,7 @@ export abstract class GaitState {
} }
public get default_feet_pos() { public get default_feet_pos() {
return new Kinematic().getDefaultFeetPos() return get(currentKinematic).getDefaultFeetPos()
} }
protected get default_height() { protected get default_height() {
+16 -8
View File
@@ -20,6 +20,15 @@ export interface target_position {
yaw: number yaw: number
} }
export interface KinematicParams {
l1: number
l2: number
l3: number
l4: number
L: number
W: number
}
const { cos, sin, atan2, acos, sqrt, max, min } = Math const { cos, sin, atan2, acos, sqrt, max, min } = Math
const DEG2RAD = 0.017453292519943 const DEG2RAD = 0.017453292519943
@@ -43,14 +52,13 @@ export default class Kinematic {
[1, 0, 0] [1, 0, 0]
] ]
constructor() { constructor(params: KinematicParams) {
this.l1 = 60.5 / 100 this.l1 = params.l1
this.l2 = 10 / 100 this.l2 = params.l2
this.l3 = 111.7 / 100 this.l3 = params.l3
this.l4 = 118.5 / 100 this.l4 = params.l4
this.L = params.L
this.L = 207.5 / 100 this.W = params.W
this.W = 78 / 100
this.mountOffsets = [ this.mountOffsets = [
[this.L / 2, 0, this.W / 2], [this.L / 2, 0, this.W / 2],
+41 -1
View File
@@ -1,7 +1,8 @@
import { api } from '$lib/api' import { api } from '$lib/api'
import { notifications } from '$lib/components/toasts/notifications' import { notifications } from '$lib/components/toasts/notifications'
import Kinematic from '$lib/kinematic'
import { persistentStore } from '$lib/utilities' import { persistentStore } from '$lib/utilities'
import { type Writable } from 'svelte/store' import { derived, type Writable } from 'svelte/store'
let featureFlagsStore: Writable<Record<string, boolean | string>> let featureFlagsStore: Writable<Record<string, boolean | string>>
@@ -19,3 +20,42 @@ export function useFeatureFlags() {
return featureFlagsStore return featureFlagsStore
} }
export const variants = {
SPOTMICRO_ESP32: {
model: '/spot_micro.urdf.xacro',
stl: '/stl.zip',
kinematics: {
l1: 60.5 / 100,
l2: 10 / 100,
l3: 111.7 / 100,
l4: 118.5 / 100,
L: 207.5 / 100,
W: 78 / 100
}
},
SPOTMICRO_YERTLE: {
model: '/yertle.URDF',
stl: '/URDF.zip',
kinematics: {
l1: 35 / 100,
l2: 0 / 100,
l3: 130 / 100,
l4: 130 / 100,
L: 240 / 100,
W: 78 / 100
}
}
}
export const currentVariant = derived(useFeatureFlags(), $flagStore => {
const variantFlag = $flagStore['variant'] as string
return variantFlag && variants[variantFlag as keyof typeof variants] ?
variants[variantFlag as keyof typeof variants]
: variants.SPOTMICRO_ESP32
})
export const currentKinematic = derived(
currentVariant,
$variant => new Kinematic($variant.kinematics)
)
+4 -3
View File
@@ -2,15 +2,16 @@ import { Color, LoaderUtils, Vector3 } from 'three'
import URDFLoader, { type URDFRobot } from 'urdf-loader' import URDFLoader, { type URDFRobot } from 'urdf-loader'
import { XacroLoader } from 'xacro-parser' import { XacroLoader } from 'xacro-parser'
import { Result } from '$lib/utilities' import { Result } from '$lib/utilities'
import { jointNames, model } from '$lib/stores' import { currentVariant, jointNames, model } from '$lib/stores'
import uzip from 'uzip' import uzip from 'uzip'
import { fileService } from '$lib/services' import { fileService } from '$lib/services'
import { get } from 'svelte/store'
let model_xml: XMLDocument let model_xml: XMLDocument
export const populateModelCache = async () => { export const populateModelCache = async () => {
await cacheModelFiles() await cacheModelFiles()
const modelRes = await loadModel('/spot_micro.urdf.xacro') const modelRes = await loadModel(get(currentVariant).model)
if (modelRes.isOk()) { if (modelRes.isOk()) {
const [urdf, JOINT_NAME] = modelRes.inner const [urdf, JOINT_NAME] = modelRes.inner
jointNames.set(JOINT_NAME) jointNames.set(JOINT_NAME)
@@ -21,7 +22,7 @@ export const populateModelCache = async () => {
} }
export const cacheModelFiles = async () => { export const cacheModelFiles = async () => {
const data = await fetch('/stl.zip') const data = await fetch(get(currentVariant).stl)
const files = uzip.parse(await data.arrayBuffer()) const files = uzip.parse(await data.arrayBuffer())
Binary file not shown.
+5
View File
@@ -0,0 +1,5 @@
# WaveFront *.mtl file (generated by Autodesk ATF)
newmtl Plastic_-_Matte_(Black)
Kd 0.098039 0.098039 0.098039
File diff suppressed because it is too large Load Diff
Binary file not shown.
+5
View File
@@ -0,0 +1,5 @@
# WaveFront *.mtl file (generated by Autodesk ATF)
newmtl Steel_-_Satin
Kd 0.627451 0.627451 0.627451
File diff suppressed because it is too large Load Diff
Binary file not shown.
+14
View File
@@ -0,0 +1,14 @@
# WaveFront *.mtl file (generated by Autodesk ATF)
newmtl Opaque(28,28,28)
Kd 0.109804 0.109804 0.109804
newmtl Steel_-_Satin
Kd 0.627451 0.627451 0.627451
newmtl Opaque(0,0,255)
Kd 0.000000 0.000000 1.000000
newmtl Opaque(202,209,238)
Kd 0.792157 0.819608 0.933333
File diff suppressed because it is too large Load Diff
Binary file not shown.
+14
View File
@@ -0,0 +1,14 @@
# WaveFront *.mtl file (generated by Autodesk ATF)
newmtl Opaque(28,28,28)
Kd 0.109804 0.109804 0.109804
newmtl Opaque(0,0,255)
Kd 0.000000 0.000000 1.000000
newmtl Opaque(202,209,238)
Kd 0.792157 0.819608 0.933333
newmtl Steel_-_Satin
Kd 0.627451 0.627451 0.627451
File diff suppressed because it is too large Load Diff
Binary file not shown.
+14
View File
@@ -0,0 +1,14 @@
# WaveFront *.mtl file (generated by Autodesk ATF)
newmtl Opaque(28,28,28)
Kd 0.109804 0.109804 0.109804
newmtl Opaque(0,0,255)
Kd 0.000000 0.000000 1.000000
newmtl Opaque(202,209,238)
Kd 0.792157 0.819608 0.933333
newmtl Steel_-_Satin
Kd 0.627451 0.627451 0.627451
File diff suppressed because it is too large Load Diff
Binary file not shown.
+14
View File
@@ -0,0 +1,14 @@
# WaveFront *.mtl file (generated by Autodesk ATF)
newmtl Opaque(28,28,28)
Kd 0.109804 0.109804 0.109804
newmtl Opaque(0,0,255)
Kd 0.000000 0.000000 1.000000
newmtl Opaque(202,209,238)
Kd 0.792157 0.819608 0.933333
newmtl Steel_-_Satin
Kd 0.627451 0.627451 0.627451
File diff suppressed because it is too large Load Diff
Binary file not shown.
+5
View File
@@ -0,0 +1,5 @@
# WaveFront *.mtl file (generated by Autodesk ATF)
newmtl Steel_-_Satin
Kd 0.627451 0.627451 0.627451
File diff suppressed because it is too large Load Diff
Binary file not shown.
+14
View File
@@ -0,0 +1,14 @@
# WaveFront *.mtl file (generated by Autodesk ATF)
newmtl Stainless_Steel_-_Satin
Kd 0.796078 0.796078 0.796078
newmtl Steel_-_Satin
Kd 0.627451 0.627451 0.627451
newmtl Plastic_-_Matte_(Black)
Kd 0.098039 0.098039 0.098039
newmtl Rubber_-_Soft
Kd 0.152941 0.152941 0.152941
File diff suppressed because it is too large Load Diff
Binary file not shown.
+402
View File
@@ -0,0 +1,402 @@
<?xml version="1.0"?>
<robot name="Dog">
<material name="white">
<color rgba="1 1 1 1" />
</material>
<material name="black">
<color rgba="0 0 0 1" />
</material>
<material name="foot_color">
<color rgba="0 0.75 1 1" />
</material>
<link name="base_link">
<visual>
<geometry>
<mesh filename="package://URDF/frame.stl" />
</geometry>
<origin rpy="0 0 3.141" xyz="0 0 0.0" />
<material name="black" />
</visual>
<inertial>
<mass value="1.5" />
<inertia ixx="0" ixy="0" ixz="0" iyy="0" iyz="0" izz="0" />
</inertial>
</link>
<!-- shell -->
<link name="frame">
<visual>
<geometry>
<mesh filename="package://URDF/shell.stl" />
</geometry>
<origin rpy="0 0 3.141" xyz="0 0 0" />
<material name="white" />
</visual>
<inertial>
<mass value="0.025" />
<inertia ixx="0.4" ixy="0.4" ixz="0.4" iyy="0.4" iyz="0.4" izz="0.4" />
</inertial>
<collision>
<geometry>
<mesh filename="package://URDF/shell.stl" />
</geometry>
<origin rpy="0 0 3.141" xyz="0 0 0.0" />
</collision>
</link>
<joint name="base_to_frame" type="fixed">
<parent link="base_link" />
<child link="frame" />
<origin xyz="0 0 0" />
</joint>
<!-- lf shoulder -->
<link name="lf_shoulder">
<visual>
<geometry>
<mesh filename="package://URDF/lf shoulder.stl" />
</geometry>
<origin rpy="3.141 3.141 0" xyz="0 0 0" />
<material name="black" />
</visual>
<inertial>
<mass value="0.025" />
<inertia ixx="0.4" ixy="0.4" ixz="0.4" iyy="0.4" iyz="0.4" izz="0.4" />
</inertial>
</link>
<joint name="lf_shoulder" type="continuous">
<parent link="base_link" />
<child link="lf_shoulder" />
<origin xyz="0.090 0.037 0" />
<axis xyz="1 0 0" />
</joint>
<link name="lf_thigh">
<visual>
<geometry>
<mesh filename="package://URDF/femur.stl" />
</geometry>
<origin rpy="1.5708 0 1.5708" xyz="0 0 0" />
<material name="black" />
</visual>
<inertial>
<mass value="0.025" />
<inertia ixx="0.4" ixy="0.4" ixz="0.4" iyy="0.4" iyz="0.4" izz="0.4" />
</inertial>
</link>
<joint name="lf_thigh" type="continuous">
<parent link="lf_shoulder" />
<child link="lf_thigh" />
<origin xyz="0.025 0.027 0 " />
<axis xyz="0 1 0" />
</joint>
<link name="lf_shin">
<visual>
<geometry>
<mesh filename="package://URDF/tibia.stl" />
</geometry>
<origin rpy="0.610865 0 -1.5708" xyz="0 0.008 0" />
<material name="black" />
</visual>
<inertial>
<mass value="0.025" />
<inertia ixx="0.4" ixy="0.4" ixz="0.4" iyy="0.4" iyz="0.4" izz="0.4" />
</inertial>
<collision>
<geometry>
<mesh filename="package://URDF/tibia.stl" />
</geometry>
<origin rpy="0.610865 0 -1.5708" xyz="0 0.008 0" />
</collision>
</link>
<joint name="lf_shin" type="continuous">
<parent link="lf_thigh" />
<child link="lf_shin" />
<origin xyz="0 0 -0.130 " />
<axis xyz="0 1 0" />
</joint>
<link name="lf_toe">
<visual>
<geometry>
<sphere radius="0.005" />
</geometry>
<origin rpy="0 0 0" xyz="0 0 0" />
<material name="foot_color" />
</visual>
<inertial>
<mass value="0.05" />
<inertia ixx="0.4" ixy="0.4" ixz="0.4" iyy="0.4" iyz="0.4" izz="0.4" />
</inertial>
<collision>
<geometry>
<sphere radius="0.020" />
</geometry>
<origin rpy="0 0 0" xyz="0 0 0" />
</collision>
</link>
<joint name="lf_toe" type="fixed">
<parent link="lf_shin" />
<child link="lf_toe" />
<origin xyz="0 0 -0.130" />
</joint>
<!-- rf shoulder -->
<link name="rf_shoulder">
<visual>
<geometry>
<mesh filename="package://URDF/rf shoulder.stl" />
</geometry>
<origin rpy="0 0 3.141" xyz="0 0 0" />
<material name="black" />
</visual>
<inertial>
<mass value="0.025" />
<inertia ixx="0.4" ixy="0.4" ixz="0.4" iyy="0.4" iyz="0.4" izz="0.4" />
</inertial>
</link>
<joint name="rf_shoulder" type="continuous">
<parent link="base_link" />
<child link="rf_shoulder" />
<origin xyz="0.090 -0.040 0" />
<axis xyz="1 0 0" />
</joint>
<link name="rf_thigh">
<visual>
<geometry>
<mesh filename="package://URDF/femur.stl" />
</geometry>
<origin rpy="4.71239 3.141 1.5708" xyz="0 0 0" />
<material name="black" />
</visual>
<inertial>
<mass value="0.025" />
<inertia ixx="0.4" ixy="0.4" ixz="0.4" iyy="0.4" iyz="0.4" izz="0.4" />
</inertial>
</link>
<joint name="rf_thigh" type="continuous">
<parent link="rf_shoulder" />
<child link="rf_thigh" />
<origin xyz="0.025 -0.027 0 " />
<axis xyz="0 1 0" />
</joint>
<link name="rf_shin">
<visual>
<geometry>
<mesh filename="package://URDF/tibia.stl" />
</geometry>
<origin rpy="0.610865 0 -1.5708" xyz="0 -0.0045 0" />
<material name="black" />
</visual>
<inertial>
<mass value="0.025" />
<inertia ixx="0.4" ixy="0.4" ixz="0.4" iyy="0.4" iyz="0.4" izz="0.4" />
</inertial>
<collision>
<geometry>
<mesh filename="package://URDF/tibia.stl" />
</geometry>
<origin rpy="0.610865 0 -1.5708" xyz="0 -0.007 0" />
</collision>
</link>
<joint name="rf_shin" type="continuous">
<parent link="rf_thigh" />
<child link="rf_shin" />
<origin xyz="0 0 -0.130 " />
<axis xyz="0 1 0" />
</joint>
<link name="rf_toe">
<visual>
<geometry>
<sphere radius="0.005" />
</geometry>
<origin rpy="0 0 0" xyz="0 0 0" />
<material name="foot_color" />
</visual>
<inertial>
<mass value="0.05" />
<inertia ixx="0.4" ixy="0.4" ixz="0.4" iyy="0.4" iyz="0.4" izz="0.4" />
</inertial>
<collision>
<geometry>
<sphere radius="0.020" />
</geometry>
<origin rpy="0 0 0" xyz="0 0 0" />
</collision>
</link>
<joint name="rf_toe" type="fixed">
<parent link="rf_shin" />
<child link="rf_toe" />
<origin xyz="0 0 -0.130" />
</joint>
<!-- lb shoulder -->
<link name="lb_shoulder">
<visual>
<geometry>
<mesh filename="package://URDF/lb shoulder.stl" />
</geometry>
<origin rpy="3.141 3.141 0" xyz="0 0 0" />
<material name="black" />
</visual>
<inertial>
<mass value="0.025" />
<inertia ixx="0.4" ixy="0.4" ixz="0.4" iyy="0.4" iyz="0.4" izz="0.4" />
</inertial>
</link>
<joint name="lb_shoulder" type="continuous">
<parent link="base_link" />
<child link="lb_shoulder" />
<origin xyz="-0.081 0.038 0" />
<axis xyz="1 0 0" />
</joint>
<link name="lb_thigh">
<visual>
<geometry>
<mesh filename="package://URDF/femur.stl" />
</geometry>
<origin rpy="1.5708 0 1.5708" xyz="0 0 0" />
<material name="black" />
</visual>
<inertial>
<mass value="0.025" />
<inertia ixx="0.4" ixy="0.4" ixz="0.4" iyy="0.4" iyz="0.4" izz="0.4" />
</inertial>
</link>
<joint name="lb_thigh" type="continuous">
<parent link="lb_shoulder" />
<child link="lb_thigh" />
<origin xyz="-0.043 0.027 0 " />
<axis xyz="0 1 0" />
</joint>
<link name="lb_shin">
<visual>
<geometry>
<mesh filename="package://URDF/tibia.stl" />
</geometry>
<origin rpy="0.610865 0 -1.5708" xyz="0 0.008 0" />
<material name="black" />
</visual>
<inertial>
<mass value="0.025" />
<inertia ixx="0.4" ixy="0.4" ixz="0.4" iyy="0.4" iyz="0.4" izz="0.4" />
</inertial>
<collision>
<geometry>
<mesh filename="package://URDF/tibia.stl" />
</geometry>
<origin rpy="0.610865 0 -1.5708" xyz="0 0.008 0" />
</collision>
</link>
<joint name="lb_shin" type="continuous">
<parent link="lb_thigh" />
<child link="lb_shin" />
<origin xyz="0 0 -0.130 " />
<axis xyz="0 1 0" />
</joint>
<link name="lb_toe">
<visual>
<geometry>
<sphere radius="0.0005" />
</geometry>
<origin rpy="0 0 0" xyz="0 0 0" />
<material name="foot_color" />
</visual>
<inertial>
<mass value="0.05" />
<inertia ixx="0.4" ixy="0.4" ixz="0.4" iyy="0.4" iyz="0.4" izz="0.4" />
</inertial>
<collision>
<geometry>
<sphere radius="0.020" />
</geometry>
<origin rpy="0 0 0" xyz="0 0 0" />
</collision>
</link>
<joint name="lb_toe" type="fixed">
<parent link="lb_shin" />
<child link="lb_toe" />
<origin xyz="0 0 -0.130" />
</joint>
<!-- rb arm -->
<link name="rb_shoulder">
<visual>
<geometry>
<mesh filename="package://URDF/rb shoulder.stl" />
</geometry>
<origin rpy="3.141 3.141 0" xyz="0 0 0" />
<material name="black" />
</visual>
<inertial>
<mass value="0.025" />
<inertia ixx="0.4" ixy="0.4" ixz="0.4" iyy="0.4" iyz="0.4" izz="0.4" />
</inertial>
</link>
<joint name="rb_shoulder" type="continuous">
<parent link="base_link" />
<child link="rb_shoulder" />
<origin xyz="-0.081 -0.040 0" />
<axis xyz="1 0 0" />
</joint>
<link name="rb_thigh">
<visual>
<geometry>
<mesh filename="package://URDF/femur.stl" />
</geometry>
<origin rpy="4.71239 3.141 1.5708" xyz="0 0 0" />
<material name="black" />
</visual>
<inertial>
<mass value="0.025" />
<inertia ixx="0.4" ixy="0.4" ixz="0.4" iyy="0.4" iyz="0.4" izz="0.4" />
</inertial>
</link>
<joint name="rb_thigh" type="continuous">
<parent link="rb_shoulder" />
<child link="rb_thigh" />
<origin xyz="-0.043 -0.027 0 " />
<axis xyz="0 1 0" />
</joint>
<link name="rb_shin">
<visual>
<geometry>
<mesh filename="package://URDF/tibia.stl" />
</geometry>
<origin rpy="0.610865 0 -1.5708" xyz="0 -0.0045 0" />
<material name="black" />
</visual>
<inertial>
<mass value="0.025" />
<inertia ixx="0.4" ixy="0.4" ixz="0.4" iyy="0.4" iyz="0.4" izz="0.4" />
</inertial>
<collision>
<geometry>
<mesh filename="package://URDF/tibia.stl" />
</geometry>
<origin rpy="0.610865 0 -1.5708" xyz="0 -0.007 0" />
</collision>
</link>
<joint name="rb_shin" type="continuous">
<parent link="rb_thigh" />
<child link="rb_shin" />
<origin xyz="0 0 -0.130 " />
<axis xyz="0 1 0" />
</joint>
<link name="rb_toe">
<visual>
<geometry>
<sphere radius="0.0005" />
</geometry>
<origin rpy="0 0 0" xyz="0 0 0" />
<material name="foot_color" />
</visual>
<inertial>
<mass value="0.05" />
<inertia ixx="0.4" ixy="0.4" ixz="0.4" iyy="0.4" iyz="0.4" izz="0.4" />
</inertial>
<collision>
<geometry>
<sphere radius="0.020" />
</geometry>
<origin rpy="0 0 0" xyz="0 0 0" />
</collision>
</link>
<joint name="rb_toe" type="fixed">
<parent link="rb_shin" />
<child link="rb_toe" />
<origin xyz="0 0 -0.130" />
</joint>
</robot>