id changes through motor panel work now (was sending new id as target

node_mode
Jake 2025-11-02 14:22:00 +08:00
parent 9036014e21
commit 5a9eee688b
5 changed files with 103 additions and 47 deletions

View File

@ -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;
}

View File

@ -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);

View File

@ -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]);

View File

@ -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
}

View File

@ -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);
}