id changes through motor panel work now (was sending new id as target
parent
9036014e21
commit
5a9eee688b
|
|
@ -143,7 +143,7 @@ export class CurveEditor {
|
|||
endPoint: { x: this.timelineLength * this.pixelsPerSecond, y: this.canvas.height / 2 }
|
||||
}
|
||||
]);
|
||||
console.log("TL LENGTH: " + this.timelineLength);
|
||||
//console.log("TL LENGTH: " + this.timelineLength);
|
||||
this.curveSets[motorID] = this.curves;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ export class ServoMotor {
|
|||
this.CURRENT_CURRENT = (payload[30] << 8) | payload[31];
|
||||
this.VOLTAGE = payload[32];
|
||||
} else {
|
||||
// Simplified constructor
|
||||
// Simplified constructor used by robot config loader
|
||||
this.CHANNEL = arg1;
|
||||
this.ID = arg2;
|
||||
|
||||
|
|
@ -44,7 +44,7 @@ export class ServoMotor {
|
|||
|
||||
|
||||
// Takes Motor object and updates simulated value, returns packet for real device
|
||||
export function writeData(motor, key) {
|
||||
export function writeData(targetID, motor, key) {
|
||||
const entry = DataMap[key];
|
||||
if (!entry) {
|
||||
throw new Error(`Invalid data key: ${key}`);
|
||||
|
|
@ -68,7 +68,7 @@ export function writeData(motor, key) {
|
|||
}
|
||||
}
|
||||
|
||||
const packet = [motor.CHANNEL, motor.ID, address, length]; // channel, id, address, value
|
||||
const packet = [motor.CHANNEL, targetID, address, length]; // channel, id, address, value
|
||||
|
||||
if (length === 2) {
|
||||
packet.push(value & 0xFF);
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@ export class NodeEditor {
|
|||
}
|
||||
|
||||
generateDefaultNodes(curveSets, motorIDs) {
|
||||
console.log("Generating Default Nodes");
|
||||
console.log(curveSets, motorIDs);
|
||||
//console.log("Generating Default Nodes");
|
||||
//console.log(curveSets, motorIDs);
|
||||
|
||||
for (var i = 0; i < motorIDs.length; i++) {
|
||||
let inputNode = this.addCurveNode(200, 20 + i * 140, "Curve", motorIDs[i]);
|
||||
|
|
|
|||
52
robot.js
52
robot.js
|
|
@ -1,4 +1,4 @@
|
|||
import { ServoMotor } from './feetechDefinitions.js';
|
||||
import { getModelType, ServoMotor } from './feetechDefinitions.js';
|
||||
|
||||
export class Robot {
|
||||
constructor(name, firmwareVersionId) {
|
||||
|
|
@ -6,7 +6,8 @@ export class Robot {
|
|||
this.firmwareVersion = { major: 0, minor: 0 };
|
||||
|
||||
// Map of position ID → ServoMotor
|
||||
this.positionMap = new Map();
|
||||
//this.positionMap = new Map();
|
||||
this.motors = [];
|
||||
}
|
||||
|
||||
// Assign a motor to a position
|
||||
|
|
@ -14,39 +15,38 @@ export class Robot {
|
|||
if (!(motor instanceof ServoMotor)) {
|
||||
throw new Error('Assigned motor must be a ServoMotor instance');
|
||||
}
|
||||
this.positionMap.set(positionId, motor);
|
||||
//this.positionMap.set(positionId, motor);
|
||||
this.motors.push(motor);
|
||||
}
|
||||
|
||||
// Get motor assigned to a position
|
||||
getMotor(positionId) {
|
||||
return this.positionMap.get(positionId);
|
||||
getMotor(motorID) {
|
||||
for (let i = 0; i < this.motors.length; i++) {
|
||||
console.log(motorID, this.motors[i].ID);
|
||||
if (String(this.motors[i].ID) === String(motorID)) {
|
||||
return this.motors[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
// Remove motor from a position
|
||||
removeMotor(positionId) {
|
||||
this.positionMap.delete(positionId);
|
||||
removeMotor(motorID) {
|
||||
this.motors = this.motors.filter(motor => motor.ID !== motorID);
|
||||
}
|
||||
|
||||
// Get all position assignments
|
||||
getAllAssignments() {
|
||||
const assignments = [];
|
||||
for (const [position, motor] of this.positionMap.entries()) {
|
||||
assignments.push({ position, motor });
|
||||
}
|
||||
return assignments;
|
||||
}
|
||||
|
||||
// Optional: Find position by motor ID
|
||||
findPositionByMotorId(id) {
|
||||
for (const [position, motor] of this.positionMap.entries()) {
|
||||
if (motor.ID === id) return position;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
// findPositionByMotorId(id) {
|
||||
// for (const [position, motor] of this.positionMap.entries()) {
|
||||
// if (motor.ID === id) return position;
|
||||
// }
|
||||
// return null;
|
||||
// }
|
||||
|
||||
static fromBytes(bytes) {
|
||||
console.log("Loading Robot from:");
|
||||
console.log(bytes);
|
||||
//console.log(bytes);
|
||||
const data = bytes instanceof Uint8Array ? bytes : Uint8Array.from(bytes);
|
||||
let offset = 0;
|
||||
|
||||
|
|
@ -73,8 +73,12 @@ export class Robot {
|
|||
const name = String.fromCharCode(...data.slice(offset, offset + nameLen));
|
||||
offset += nameLen;
|
||||
|
||||
const modelMajor = data[offset++];
|
||||
const modelMinor = data[offset++];
|
||||
const modelType = getModelType(modelMajor, modelMinor);
|
||||
|
||||
const position = (data[offset++] << 8) | data[offset++];
|
||||
const motor = new ServoMotor(0, motorID, null, name);
|
||||
const motor = new ServoMotor(0, motorID, modelType, name);
|
||||
robot.assignMotor(motorID, motor); // motorID used as position ID
|
||||
}
|
||||
|
||||
|
|
|
|||
86
script.js
86
script.js
|
|
@ -34,7 +34,42 @@ window.onload = () => {
|
|||
|
||||
|
||||
|
||||
const dialColors = ['red', 'green', 'blue', 'orange', 'purple'];
|
||||
const dialColors = [
|
||||
'#F50057', // Raspberry
|
||||
'#6200EA', // Deep Violet
|
||||
'#FFB400', // Bright Amber
|
||||
'#2979FF', // Royal Blue
|
||||
'#FF5252', // Coral Red
|
||||
'#00C853', // Vivid Green
|
||||
'#FF80AB', // Bubblegum
|
||||
'#00B8D4', // Sky Cyan
|
||||
'#FF9100', // Neon Orange
|
||||
'#651FFF', // Electric Indigo
|
||||
'#FF4F81', // Vibrant Pink
|
||||
'#AEEA00', // Chartreuse
|
||||
'#FFAB40', // Sunset Orange
|
||||
'#00E5FF', // Aqua
|
||||
'#FF6F00', // Vivid Orange
|
||||
'#64DD17', // Leaf Green
|
||||
'#FFEA00', // Vivid Yellow
|
||||
'#C51162', // Deep Rose
|
||||
'#40C4FF', // Sky Blue
|
||||
'#D500F9', // Vivid Purple
|
||||
'#76FF03', // Lime Green
|
||||
'#FF4081', // Hot Pink
|
||||
'#00B0FF', // Electric Blue
|
||||
'#FF1744', // Crimson
|
||||
'#B388FF', // Soft Violet
|
||||
'#1DE9B6', // Minty Teal
|
||||
'#AA00FF', // Vivid Lavender
|
||||
'#FFB347', // Pastel Orange
|
||||
'#00C1D4', // Bright Cyan
|
||||
'#7C4DFF' // Neon Purple
|
||||
];
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
let dials = [];
|
||||
const frameSlider = document.getElementById('frameSlider');
|
||||
|
|
@ -44,7 +79,7 @@ window.onload = () => {
|
|||
|
||||
|
||||
const curveCanvas = document.getElementById('curveCanvas');
|
||||
const curveEditor = new CurveEditor(curveCanvas, 6, frameSlider);
|
||||
const curveEditor = new CurveEditor(curveCanvas, 10, frameSlider);
|
||||
|
||||
|
||||
// Animation File List
|
||||
|
|
@ -77,13 +112,14 @@ window.onload = () => {
|
|||
console.log(connectedRobot);
|
||||
let motorIDList = []
|
||||
clearDials();
|
||||
for (const [position, motor] of connectedRobot.positionMap.entries()) {
|
||||
console.log(`Assigning ${position} motor with ID ${motor.ID}`);
|
||||
for (const motor of connectedRobot.motors) {
|
||||
curveEditor.addChannel(motor.ID);
|
||||
motorIDList.push(motor.ID);
|
||||
addDial(motor.ID, motor.NAME);
|
||||
}
|
||||
setSelectedMotor(10);
|
||||
if (connectedRobot.motors.length > 0){
|
||||
setSelectedMotor(connectedRobot.motors[0].ID);
|
||||
}
|
||||
|
||||
|
||||
nodeEditor = new NodeEditor(nodeCanvas, {
|
||||
|
|
@ -95,7 +131,7 @@ window.onload = () => {
|
|||
|
||||
|
||||
function setSelectedMotor(motorID) {
|
||||
console.log(motorID);
|
||||
//console.log(motorID);
|
||||
curveEditor.selectMotor(motorID);
|
||||
selectedDial = motorID;
|
||||
|
||||
|
|
@ -109,7 +145,7 @@ window.onload = () => {
|
|||
}
|
||||
});
|
||||
|
||||
console.log("Selected motor:", motorID);
|
||||
//console.log("Selected motor:", motorID);
|
||||
// Any other logic you want to run
|
||||
|
||||
|
||||
|
|
@ -134,8 +170,7 @@ window.onload = () => {
|
|||
// Retrieve motor by position
|
||||
//console.log(robot.getMotor('eyelids'));
|
||||
|
||||
// List all assignments
|
||||
console.log(robot.getAllAssignments());
|
||||
|
||||
return robot;
|
||||
}
|
||||
|
||||
|
|
@ -417,12 +452,15 @@ window.onload = () => {
|
|||
|
||||
case 0x06: // CMD_MESSAGE
|
||||
|
||||
console.log(`Message Recieved`);
|
||||
//console.log(`Message Recieved`);
|
||||
const decoder = new TextDecoder();
|
||||
console.log(payload);
|
||||
//console.log(payload);
|
||||
const stringPayload = decoder.decode(new Uint8Array(payload));
|
||||
console.log(stringPayload);
|
||||
//console.log(stringPayload);
|
||||
document.getElementById('log').value += "MSG: " + stringPayload + `\n`;
|
||||
const logBox = document.getElementById('log');
|
||||
logBox.value += "MSG: " + stringPayload + `\n`;
|
||||
logBox.scrollTop = logBox.scrollHeight;
|
||||
// 🔹 Do something with the file
|
||||
//handleLoadedFile(fileData);
|
||||
break;
|
||||
|
|
@ -479,15 +517,21 @@ window.onload = () => {
|
|||
});
|
||||
|
||||
function handlePositionStreamPacket(data) {
|
||||
for (let i = 0; i < 5; i++) {
|
||||
const high = data[i * 2]; // High byte
|
||||
const low = data[i * 2 + 1]; // Low byte
|
||||
const value = (high << 8) | low; // Combine into uint16_t
|
||||
const motorCount = Math.floor(data.length / 2); // Each motor uses 2 bytes
|
||||
|
||||
for (let i = 0; i < motorCount; i++) {
|
||||
const high = data[i * 2]; // High byte
|
||||
const low = data[i * 2 + 1]; // Low byte
|
||||
const value = (high << 8) | low; // Combine into uint16_t
|
||||
|
||||
if (dials[i]) {
|
||||
dials[i].value = value;
|
||||
}
|
||||
}
|
||||
|
||||
console.log(data);
|
||||
}
|
||||
|
||||
function handleLoadedFile(data) {
|
||||
const raw = new Uint8Array(data);
|
||||
const view = new DataView(raw.buffer);
|
||||
|
|
@ -1033,7 +1077,9 @@ window.onload = () => {
|
|||
let dataKey = packets[i].title;
|
||||
let value = packets[i].value;
|
||||
servoMotor[dataKey] = value;
|
||||
let dataPacket = writeData(servoMotor, dataKey);
|
||||
let dataPacket = writeData(packets[i].id, servoMotor, dataKey);
|
||||
//dataPacket[1] = packets[i].id;
|
||||
console.log(dataPacket);
|
||||
serial.requestWriteData(dataPacket);
|
||||
}
|
||||
console.log(servoMotors);
|
||||
|
|
@ -1073,6 +1119,12 @@ window.onload = () => {
|
|||
console.log(motor.MODEL, motor.POSITION, motor.CURRENT_SPEED);
|
||||
servoMotors[motor.CHANNEL].push(motor);
|
||||
|
||||
// If motor is in robot config already, grab the name
|
||||
let configMotor = connectedRobot.getMotor(motor.ID);
|
||||
if (configMotor != null){
|
||||
motor.NAME = configMotor.NAME;
|
||||
}
|
||||
|
||||
insertTableRow(motor);
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue