Skip to content
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
142 changes: 139 additions & 3 deletions src/controls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export class URDFControls extends GUI {
private _workspaceFolder: any;
private _sceneFolder: any;
private _jointsFolder: any;
private _editorFolder: any;
private _workingPath = '';

controls: any = {
Expand All @@ -26,7 +27,8 @@ export class URDFControls extends GUI {
height: {}
},
joints: {},
lights: {}
lights: {},
editor: {}
};

/**
Expand Down Expand Up @@ -59,6 +61,9 @@ export class URDFControls extends GUI {

this._sceneFolder = this.addFolder('Scene');
this._sceneFolder.domElement.setAttribute('class', 'dg scene-folder');

this._editorFolder = this.addFolder('Editor');
this._editorFolder.domElement.setAttribute('class', 'dg editor-folder');
}

/**
Expand All @@ -82,6 +87,13 @@ export class URDFControls extends GUI {
return this._jointsFolder;
}

/**
* Retrieves the folder with editor settings
*/
get editorFolder() {
return this._editorFolder;
}

/**
* Checks if a given object is empty {}
*
Expand All @@ -92,6 +104,28 @@ export class URDFControls extends GUI {
return Object.keys(obj).length === 0;
}

/**
* Restricts input on a control to numeric and special characters.
*
* @param control - The dat.gui controller to modify.
*/
private _enforceNumericInput(control: any): void {
const inputElement = control.domElement as HTMLInputElement;

inputElement.addEventListener('input', (event: Event) => {
const target = event.target as HTMLInputElement;
const originalValue = target.value;

// Remove any characters that aren't digits, spaces, periods, or minus signs
const filteredValue = originalValue.replace(/[^\d.\s-]/g, '');

if (originalValue !== filteredValue) {
target.value = filteredValue;
control.updateDisplay();
}
});
}

/**
* Creates an input box and a button to modify the working path
*
Expand Down Expand Up @@ -155,6 +189,9 @@ export class URDFControls extends GUI {
stepSize
);

// Enforce input validation
this._enforceNumericInput(this.controls.scene.height);

this._sceneFolder.open();
}
return this.controls.scene;
Expand Down Expand Up @@ -200,7 +237,7 @@ export class URDFControls extends GUI {
return;
}

const stepSize = (limitMax - limitMin) / 100.0;
const stepSize = (limitMax - limitMin) / 100;
const initValue = joints[name].jointValue[0];

this.controls.joints[name] = this._jointsFolder.add(
Expand All @@ -210,6 +247,7 @@ export class URDFControls extends GUI {
limitMax,
stepSize
);
this._enforceNumericInput(this.controls.joints[name]);
});
this._jointsFolder.open();
}
Expand Down Expand Up @@ -385,11 +423,109 @@ export class URDFControls extends GUI {
.name('Show Helper')
};

this._enforceNumericInput(
this.controls.lights.directional.position.altitude
);
this._enforceNumericInput(
this.controls.lights.directional.position.azimuth
);
this._enforceNumericInput(this.controls.lights.directional.intensity);
this._enforceNumericInput(this.controls.lights.ambient.intensity);
this._enforceNumericInput(this.controls.lights.hemisphere.intensity);

// Open Scene (lights) and directional subfolder
this._sceneFolder.open();
directionalFolder.open();
}

return this.controls.lights;
}

/**
* Creates controls for the editor mode
*
* @returns - The controls to trigger callbacks when editor settings change
*/
createEditorControls(addJointCallback: () => void, linkNames: string[] = []) {
if (this._isEmpty(this.controls.editor)) {
const editorSettings = {
'Editor Mode': false,
'Parent Link': 'none',
'Child Link': 'none',
'Joint Name': 'new_joint',
'Joint Type': 'revolute',
'Origin XYZ': '0 0 0',
'Origin RPY': '0 0 0',
'Axis XYZ': '0 0 1',
'Lower Limit': '0.0',
'Upper Limit': '0.0',
Effort: '0.0',
Velocity: '0.0',
'Add Joint': addJointCallback
};

const dropdownOptions = ['none', ...linkNames];

this.controls.editor.mode = this._editorFolder.add(
editorSettings,
'Editor Mode'
);
this.controls.editor.parent = this._editorFolder
.add(editorSettings, 'Parent Link', dropdownOptions)
.listen();
this.controls.editor.child = this._editorFolder
.add(editorSettings, 'Child Link', dropdownOptions)
.listen();
this.controls.editor.name = this._editorFolder.add(
editorSettings,
'Joint Name'
);
this.controls.editor.type = this._editorFolder.add(
editorSettings,
'Joint Type',
['revolute', 'continuous', 'prismatic', 'fixed', 'floating', 'planar']
);

// Add origin and axis controls
this.controls.editor.origin_xyz = this._editorFolder
.add(editorSettings, 'Origin XYZ')
.name('Origin XYZ');
this.controls.editor.origin_rpy = this._editorFolder
.add(editorSettings, 'Origin RPY')
.name('Origin RPY');
this.controls.editor.axis_xyz = this._editorFolder
.add(editorSettings, 'Axis XYZ')
.name('Axis XYZ');

// Add limit controls
this.controls.editor.lower = this._editorFolder
.add(editorSettings, 'Lower Limit')
.name('Lower Limit');
this.controls.editor.upper = this._editorFolder
.add(editorSettings, 'Upper Limit')
.name('Upper Limit');
this.controls.editor.effort = this._editorFolder
.add(editorSettings, 'Effort')
.name('Effort');
this.controls.editor.velocity = this._editorFolder
.add(editorSettings, 'Velocity')
.name('Velocity');

this._enforceNumericInput(this.controls.editor.origin_xyz);
this._enforceNumericInput(this.controls.editor.origin_rpy);
this._enforceNumericInput(this.controls.editor.axis_xyz);
this._enforceNumericInput(this.controls.editor.lower);
this._enforceNumericInput(this.controls.editor.upper);
this._enforceNumericInput(this.controls.editor.effort);
this._enforceNumericInput(this.controls.editor.velocity);

this.controls.editor.add = this._editorFolder.add(
editorSettings,
'Add Joint'
);

this._editorFolder.open();
}

return this.controls.editor;
}
}
Loading
Loading