Cleanup helper scripts. Closes #7

This commit is contained in:
osiu97
2026-07-08 20:35:59 +02:00
parent 75ce38daf7
commit 1a94ca3947
11 changed files with 3 additions and 1 deletions
+10
View File
@@ -0,0 +1,10 @@
const fs = require('fs');
const { execSync } = require('child_process');
try {
const output = execSync('git log -p -3 src/main.cpp', { cwd: 'm:/Nextcloud/IoT/esp32s3-wiji' });
fs.writeFileSync('m:/Nextcloud/IoT/esp32s3-wiji/git_history.txt', output);
console.log('Success');
} catch (e) {
console.log('Error', e.message);
}
+54
View File
@@ -0,0 +1,54 @@
import json
import os
svg_lines = [
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 175">',
' <!-- Background -->',
' <rect width="300" height="175" fill="#fdf6e3"/>',
' <!-- Decoration on left -->',
' <circle cx="75" cy="87.5" r="60" fill="none" stroke="#eee8d5" stroke-width="4" stroke-dasharray="10,5"/>',
' <circle cx="75" cy="87.5" r="40" fill="none" stroke="#eee8d5" stroke-width="2" />',
' <text x="75" y="87.5" fill="#93a1a1" font-family="sans-serif" font-size="12" text-anchor="middle" font-weight="bold">MECHANISM</text>',
' <text x="75" y="102.5" fill="#93a1a1" font-family="sans-serif" font-size="10" text-anchor="middle">CLEARANCE</text>',
]
# X from 150 to 300
for row in range(9):
y_base = 25 + row * 16
svg_lines.append(f' <line x1="155" y1="{y_base}" x2="295" y2="{y_base}" stroke="#e0e0e0" stroke-width="1"/>')
svg_lines.append(f' <line x1="155" y1="{y_base-5}" x2="295" y2="{y_base-5}" stroke="#e0e0e0" stroke-width="0.5" stroke-dasharray="2,2"/>')
svg_lines.append(f' <line x1="155" y1="{y_base-10}" x2="295" y2="{y_base-10}" stroke="#e0e0e0" stroke-width="1"/>')
spots = []
alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
for i, letter in enumerate(alphabet):
col = i % 3
row = i // 3
svg_x = 175 + col * 50
svg_y = 25 + row * 16
phys_x = svg_x - 150
phys_y = 145 - svg_y
spots.append({
"id": letter,
"label": f"{letter.upper()}{letter.lower()}",
"x": phys_x,
"y": phys_y
})
text_str = f' <text x="{svg_x}" y="{svg_y}" fill="#268bd2" font-family="cursive, \'Comic Sans MS\', sans-serif" font-size="14" font-style="italic" text-anchor="middle">{letter.upper()}{letter.lower()}</text>'
svg_lines.append(text_str)
svg_lines.append('</svg>')
with open('web/assets/backgrounds/portrait-right/bg.svg', 'w') as f:
f.write('\n'.join(svg_lines))
with open('web/assets/backgrounds/portrait-right/spots.json', 'w') as f:
json.dump({
"bounds": { "xMin": -150, "xMax": 150, "yMin": -30, "yMax": 145 },
"spots": spots
}, f, indent=2)
+7
View File
@@ -0,0 +1,7 @@
const { execSync } = require('child_process');
const fs = require('fs');
try {
const log = execSync('git log -p -n 10 src/main.cpp', { encoding: 'utf8' });
fs.writeFileSync('git_log.txt', log);
} catch(e) {}
+20
View File
@@ -0,0 +1,20 @@
const d2 = 12.9, l1 = 85.0, l2 = 110.0;
for(let t1=0; t1<360; t1++){
for(let t2=0; t2<360; t2++){
let th1 = t1 * Math.PI/180; let th2 = t2 * Math.PI/180;
let e1x = -d2 + l1*Math.cos(th1); let e1y = l1*Math.sin(th1);
let e2x = d2 + l1*Math.cos(th2); let e2y = l1*Math.sin(th2);
let dx = e2x - e1x; let dy = e2y - e1y;
let dist = Math.sqrt(dx*dx + dy*dy);
if(dist < 1e-6 || dist > 2*l2) continue;
let a = dist/2; let h = Math.sqrt(Math.max(0, l2*l2 - a*a));
let mx = (e1x+e2x)/2; let my = (e1y+e2y)/2;
let px1 = mx + h*(dy/dist); let py1 = my + h*(-dx/dist);
let px2 = mx - h*(dy/dist); let py2 = my - h*(-dx/dist);
let useFirst = py1 >= py2;
let ex = useFirst ? px1 : px2; let ey = useFirst ? py1 : py2;
if(Math.abs(ex - 114.4) < 1.0 && Math.abs(ey - 112.7) < 1.0){
console.log('Match: t1=' + t1 + ' t2=' + t2 + ' -> ' + ex.toFixed(1) + ', ' + ey.toFixed(1));
}
}
}
+48
View File
@@ -0,0 +1,48 @@
import math
d2 = 12.9
l1 = 85.0
l2 = 110.0
for t1 in range(360):
for t2 in range(360):
th1 = math.radians(t1)
th2 = math.radians(t2)
e1x = -d2 + l1 * math.cos(th1)
e1y = l1 * math.sin(th1)
e2x = d2 + l1 * math.cos(th2)
e2y = l1 * math.sin(th2)
dx = e2x - e1x
dy = e2y - e1y
dist = math.sqrt(dx*dx + dy*dy)
if dist < 1e-6 or dist > 2*l2:
continue
a = dist / 2
h2 = l2*l2 - a*a
if h2 < 0:
h2 = 0
h = math.sqrt(h2)
mx = (e1x + e2x) / 2
my = (e1y + e2y) / 2
px1 = mx + h * (dy / dist)
py1 = my + h * (-dx / dist)
px2 = mx - h * (dy / dist)
py2 = my - h * (-dx / dist)
if py1 >= py2:
ex = px1
ey = py1
else:
ex = px2
ey = py2
if abs(ex - 114.4) < 1.0 and abs(ey - 112.7) < 1.0:
print(f"Match: t1={t1} t2={t2} -> {ex:.1f}, {ey:.1f}")
+55
View File
@@ -0,0 +1,55 @@
import asyncio
import sys
try:
from bleak import BleakScanner, BleakClient
except ImportError:
print("Please install bleak first: pip install bleak")
sys.exit(1)
DEVICE_NAME = "WijiBoard"
SERVICE_UUID = "18f3b235-9831-4c75-8ec0-210469b820a0"
CMD_UUID = "cd083b06-4447-4cf3-a7c3-322ecf802ce4"
STATUS_UUID = "82e38c5b-d3ab-41d1-861c-b84dc6bb1e03"
async def main():
print(f"Scanning for {DEVICE_NAME}...")
devices = await BleakScanner.discover(timeout=5.0)
target_device = None
for d in devices:
if d.name == DEVICE_NAME:
target_device = d
break
if not target_device:
print(f"Could not find {DEVICE_NAME}. Make sure it is powered on and advertising.")
return
print(f"Found {DEVICE_NAME} at {target_device.address}. Connecting...")
async with BleakClient(target_device.address) as client:
print(f"Connected: {client.is_connected}")
# Setup notifications
def notification_handler(sender, data):
print(f"[STATUS UPDATE] {data.decode('utf-8')}")
print("Subscribing to status characteristic...")
try:
await client.start_notify(STATUS_UUID, notification_handler)
print("Successfully subscribed!")
except Exception as e:
print(f"Failed to subscribe: {e}")
# Send a test command
test_cmd = "S1+100"
print(f"Sending test command: '{test_cmd}'...")
await client.write_gatt_char(CMD_UUID, test_cmd.encode('utf-8'), response=False)
print("Waiting 5 seconds to receive any status updates...")
await asyncio.sleep(5.0)
print("Disconnecting...")
if __name__ == "__main__":
asyncio.run(main())
+41
View File
@@ -0,0 +1,41 @@
import math
d2 = 12.9
l1 = 85.0
l2 = 110.0
t1_deg = 474 / 2048.0 * 360.0
t2_deg = 530 / 2048.0 * 360.0
th1 = math.radians(t1_deg)
th2 = math.radians(t2_deg)
e1x = -d2 + l1 * math.cos(th1)
e1y = l1 * math.sin(th1)
e2x = d2 + l1 * math.cos(th2)
e2y = l1 * math.sin(th2)
dx = e2x - e1x
dy = e2y - e1y
dist = math.sqrt(dx*dx + dy*dy)
a = dist / 2
h = math.sqrt(l2*l2 - a*a)
mx = (e1x + e2x) / 2
my = (e1y + e2y) / 2
px1 = mx + h * (dy / dist)
py1 = my + h * (-dx / dist)
px2 = mx - h * (dy / dist)
py2 = my - h * (-dx / dist)
ex = px1 if py1 >= py2 else px2
ey = py1 if py1 >= py2 else py2
with open("output.txt", "w") as f:
f.write(f"End Effector: {ex:.1f}, {ey:.1f}\n")
f.write(f"Elbow 1: {e1x:.1f}, {e1y:.1f}\n")
f.write(f"Elbow 2: {e2x:.1f}, {e2y:.1f}\n")
+39
View File
@@ -0,0 +1,39 @@
const ARM = { d2: 12.9, l1: 85.0, l2: 110.0, STEPS_PER_REV: 2048 };
const HOME_STEPS = { m1: 1024, m2: 0 };
function solve(x, y) {
const { d2, l1, l2 } = ARM;
const xpd = x + d2;
const t = Math.sqrt(xpd * xpd + y * y);
const cosW2 = (l2 * l2 - t * t - l1 * l1) / (-2 * l1 * t);
const r = Math.atan2(y, xpd);
const w2 = Math.acos(cosW2);
const theta1 = r + w2;
const xmd = x - d2;
const s = Math.sqrt(xmd * xmd + y * y);
const cosW1 = (l2 * l2 - s * s - l1 * l1) / (-2 * l1 * s);
const q = Math.atan2(y, xmd);
const w1 = Math.acos(cosW1);
const theta2 = q - w1;
return { theta1, theta2 };
}
function radToSteps(rad) { return Math.round((rad / (2 * Math.PI)) * ARM.STEPS_PER_REV); }
const targetX = 115, targetY = 113;
const { theta1, theta2 } = solve(targetX, targetY);
console.log(`Target: (${targetX}, ${targetY})`);
console.log(`theta1: ${theta1 * 180 / Math.PI} deg`);
console.log(`theta2: ${theta2 * 180 / Math.PI} deg`);
const newSteps1 = radToSteps(theta1);
const newSteps2 = radToSteps(theta2);
console.log(`newSteps1: ${newSteps1}`);
console.log(`newSteps2: ${newSteps2}`);
console.log(`delta1 from HOME_STEPS.m1 (1024): ${newSteps1 - HOME_STEPS.m1}`);
console.log(`delta2 from HOME_STEPS.m2 (0): ${newSteps2 - HOME_STEPS.m2}`);
const delta1_old = newSteps1 - (-1024);
console.log(`delta1 from OLD_HOME_STEPS.m1 (-1024): ${delta1_old}`);
+47
View File
@@ -0,0 +1,47 @@
const fs = require('fs');
const d2 = 12.9;
const l1 = 85;
const l2 = 110;
function stepsToRad(steps) {
return (steps / 2048) * 2 * Math.PI;
}
function render(steps1, steps2) {
const t1 = stepsToRad(steps1);
const t2 = stepsToRad(steps2);
const e1x = -d2 + l1 * Math.cos(t1);
const e1y = l1 * Math.sin(t1);
const e2x = d2 + l1 * Math.cos(t2);
const e2y = l1 * Math.sin(t2);
const dx = e2x - e1x;
const dy = e2y - e1y;
const dist = Math.sqrt(dx*dx + dy*dy);
let endX = 0, endY = 0;
if (dist <= 2*l2 && dist >= 1e-6) {
const a = dist / 2;
const h = Math.sqrt(l2*l2 - a*a);
const mx = (e1x + e2x) / 2;
const my = (e1y + e2y) / 2;
const px1 = mx + h * (dy / dist);
const py1 = my + h * (-dx / dist);
const px2 = mx - h * (dy / dist);
const py2 = my - h * (-dx / dist);
if (py1 >= py2) { endX = px1; endY = py1; }
else { endX = px2; endY = py2; }
}
console.log(`steps1=${steps1}, steps2=${steps2}`);
console.log(`t1=${(t1*180/Math.PI).toFixed(1)}°, t2=${(t2*180/Math.PI).toFixed(1)}°`);
console.log(`e1=(${e1x.toFixed(1)}, ${e1y.toFixed(1)})`);
console.log(`e2=(${e2x.toFixed(1)}, ${e2y.toFixed(1)})`);
console.log(`end=(${endX.toFixed(1)}, ${endY.toFixed(1)})`);
}
render(854, 41);
render(-41, 967);