curves now sending/receiving correctly. Y values are now converted to Int16 values to allow handles to dip below 0
parent
d67cba4c6f
commit
55b2c178e6
|
|
@ -8,6 +8,8 @@ export class CurveEditor {
|
|||
this.offset = { x: 0, y: 0 };
|
||||
this.pixelsPerSecond = 48;
|
||||
|
||||
this.exportRange = [0, 4095];
|
||||
|
||||
this.currentTime = timelineLength * this.pixelsPerSecond / 2;
|
||||
|
||||
this.motorButtons = {
|
||||
|
|
@ -40,15 +42,15 @@ export class CurveEditor {
|
|||
this.panStart = { x: 0, y: 0 };
|
||||
|
||||
// Default curve
|
||||
// this.setCurves([
|
||||
// {
|
||||
// startPoint: { x: this.valueToX(0), y: this.valueToY(0) },
|
||||
// startPointHandle: { x: this.valueToX(timelineLength / 2), y: this.valueToY(0.5) },
|
||||
// endPointHandle: { x: this.valueToX(timelineLength / 2), y: this.valueToY(-0.5) },
|
||||
// endPoint: { x: this.valueToX(timelineLength), y: this.valueToY(0) }
|
||||
// }
|
||||
// ]);
|
||||
// this.curveSets[this.selectedMotorID] = this.curves;
|
||||
this.setCurves([
|
||||
{
|
||||
startPoint: { x: this.valueToX(0), y: this.valueToY(0) },
|
||||
startPointHandle: { x: this.valueToX(timelineLength / 2), y: this.valueToY(0.5) },
|
||||
endPointHandle: { x: this.valueToX(timelineLength / 2), y: this.valueToY(-0.5) },
|
||||
endPoint: { x: this.valueToX(timelineLength), y: this.valueToY(0) }
|
||||
}
|
||||
]);
|
||||
this.curveSets[this.selectedMotorID] = this.curves;
|
||||
|
||||
// let othercurves = [
|
||||
// {
|
||||
|
|
@ -71,7 +73,7 @@ export class CurveEditor {
|
|||
// this.curveSets[7] = othercurves;
|
||||
|
||||
|
||||
// this.setSelectedMotor(5);
|
||||
this.setSelectedMotor(4);
|
||||
|
||||
this.initEvents();
|
||||
this.draw();
|
||||
|
|
@ -115,10 +117,31 @@ export class CurveEditor {
|
|||
return (this.canvas.height / 2 - v * (this.canvas.height / 2)) * this.scale + this.offset.y;
|
||||
}
|
||||
|
||||
// Maps pixel value of y axis to -1 to 1 normalised value
|
||||
yToValue(y) {
|
||||
return ((this.canvas.height / 2 - (y - this.offset.y) / this.scale) / (this.canvas.height / 2));
|
||||
}
|
||||
|
||||
// Maps normalised -1 to 1 value to motor range (0, 4095)
|
||||
yToExportRange(y) {
|
||||
const [minOut, maxOut] = this.exportRange;
|
||||
// Normalize y from [-1, 1] to [0, 1]
|
||||
const normalized = (this.yToValue(y) + 1) / 2;
|
||||
// Scale to export range
|
||||
return Math.round(normalized * (maxOut - minOut) + minOut);
|
||||
}
|
||||
|
||||
exportRangeToY(value) {
|
||||
const [minOut, maxOut] = this.exportRange;
|
||||
// Reverse the scaling
|
||||
const normalized = (value - minOut) / (maxOut - minOut);
|
||||
// Convert from [0, 1] back to [-1, 1]
|
||||
const yValue = normalized * 2 - 1;
|
||||
// Apply inverse mapping from value space to editor Y
|
||||
return this.valueToY(yValue);
|
||||
}
|
||||
|
||||
|
||||
valueToX(t) {
|
||||
return t * this.pixelsPerSecond * this.scale + this.offset.x;
|
||||
}
|
||||
|
|
@ -635,6 +658,8 @@ export class CurveEditor {
|
|||
curve.startPointHandle.y += deltaY;
|
||||
|
||||
this.dragControlPoint(curve, 'startPointHandle', curve.startPointHandle.x, curve.startPointHandle.y, index);
|
||||
|
||||
console.log(this.yToExportRange(curve.startPoint.y));
|
||||
} else if (key === 'endPoint') {
|
||||
const oldX = curve.endPoint.x;
|
||||
const oldY = curve.endPoint.y;
|
||||
|
|
@ -660,6 +685,7 @@ export class CurveEditor {
|
|||
this.dragControlPoint(curve, 'endPointHandle', curve.endPointHandle.x, curve.endPointHandle.y, index);
|
||||
|
||||
const nextCurve = this.curves[index + 1];
|
||||
console.log(curve.endPoint.y);
|
||||
if (nextCurve) {
|
||||
nextCurve.startPoint.x = curve.endPoint.x;
|
||||
nextCurve.startPoint.y = curve.endPoint.y;
|
||||
|
|
|
|||
|
|
@ -155,7 +155,7 @@
|
|||
|
||||
|
||||
<div class="tab-pane fade" id="animation" role="tabpanel" aria-labelledby="animation-tab">
|
||||
<canvas id="curveCanvas" width="900" height="300"></canvas>
|
||||
<canvas id="curveCanvas" width="900" height="600"></canvas>
|
||||
<div style="margin-top: 10px; text-align: center;">
|
||||
<input type="range" id="timeSlider" min="0" step="1" style="width: 80%;">
|
||||
</div>
|
||||
|
|
|
|||
32
script.js
32
script.js
|
|
@ -424,34 +424,34 @@ window.onload = () => {
|
|||
offset += 1;
|
||||
const startTime = view.getUint16(offset, true); offset += 2;
|
||||
const endTime = view.getUint16(offset, true); offset += 2;
|
||||
const startPointY = view.getUint16(offset, true); offset += 2;
|
||||
const startPointY = view.getInt16(offset, true); offset += 2;
|
||||
const startHandleX = view.getUint16(offset, true); offset += 2;
|
||||
const startHandleY = view.getUint16(offset, true); offset += 2;
|
||||
const startHandleY = view.getInt16(offset, true); offset += 2;
|
||||
const endHandleX = view.getUint16(offset, true); offset += 2;
|
||||
const endHandleY = view.getUint16(offset, true); offset += 2;
|
||||
const endPointY = view.getUint16(offset, true); offset += 2;
|
||||
const endHandleY = view.getInt16(offset, true); offset += 2;
|
||||
const endPointY = view.getInt16(offset, true); offset += 2;
|
||||
|
||||
console.log("RECEIVED VALUES RAW:");
|
||||
console.log(startTime, endTime);
|
||||
console.log(startTime, endTime, startPointY, endPointY);
|
||||
|
||||
const toFloat = v => (v / 65535) * 2 - 1;
|
||||
|
||||
const curve = {
|
||||
startPoint: {
|
||||
x: startTime,
|
||||
y: curveEditor.valueToY(toFloat(startPointY))
|
||||
y: curveEditor.exportRangeToY(startPointY)
|
||||
},
|
||||
startPointHandle: {
|
||||
x: startHandleX,
|
||||
y: curveEditor.valueToY(toFloat(startHandleY))
|
||||
y: curveEditor.exportRangeToY(startHandleY)
|
||||
},
|
||||
endPointHandle: {
|
||||
x: endHandleX,
|
||||
y: curveEditor.valueToY(toFloat(endHandleY))
|
||||
y: curveEditor.exportRangeToY(endHandleY)
|
||||
},
|
||||
endPoint: {
|
||||
x: endTime,
|
||||
y: curveEditor.valueToY(toFloat(endPointY))
|
||||
y: curveEditor.exportRangeToY(endPointY)
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -561,23 +561,27 @@ window.onload = () => {
|
|||
view.setUint16(offset, curveCount, true); offset += 2;
|
||||
|
||||
// 🔹 Curve segments
|
||||
|
||||
curveSegments.forEach(seg => {
|
||||
view.setUint8(offset++, seg.motorID);
|
||||
view.setUint16(offset, seg.startTime, true); offset += 2;
|
||||
view.setUint16(offset, seg.endTime, true); offset += 2;
|
||||
view.setUint16(offset, seg.startPointY, true); offset += 2;
|
||||
view.setInt16(offset, curveEditor.yToExportRange(seg.startPointY), true); offset += 2;
|
||||
|
||||
console.log(curveEditor.yToExportRange(seg.startPointY));
|
||||
view.setUint16(offset, seg.startHandleX, true); offset += 2;
|
||||
view.setUint16(offset, seg.startHandleY, true); offset += 2;
|
||||
console.log("STARTHANDLEY: " + seg.startHandleY);
|
||||
view.setInt16(offset, curveEditor.yToExportRange(seg.startHandleY), true); offset += 2;
|
||||
view.setUint16(offset, seg.endHandleX, true); offset += 2;
|
||||
view.setUint16(offset, seg.endHandleY, true); offset += 2;
|
||||
view.setUint16(offset, seg.endPointY, true); offset += 2;
|
||||
view.setInt16(offset, curveEditor.yToExportRange(seg.endHandleY), true); offset += 2;
|
||||
view.setInt16(offset, curveEditor.yToExportRange(seg.endPointY), true); offset += 2;
|
||||
});
|
||||
console.log("🧵 Curve segments packed:", curveSegments.length);
|
||||
console.log(curveSegments);
|
||||
|
||||
|
||||
// 🔹 Send to ESP32
|
||||
const payload = new Uint8Array(buffer);
|
||||
console.log()
|
||||
console.log(payload);
|
||||
serial.saveFile(payload); // CMD_SAVE_ANIMATION
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue