pverseer rambling at 430am

This commit is contained in:
legop3
2026-05-02 04:35:20 -04:00
parent 0f97382f42
commit e8f6fb9654
4 changed files with 86 additions and 23 deletions
+35
View File
@@ -0,0 +1,35 @@
# overseer v2 (will have a name rather than overseer.)
- name ideas:
- allied mastercomputer
- maybe it could rename itself? rarely?
- AUTO
- servermaster
- LCARS
- current model is mistral-small:24b
- currently runs at a pretty fast rate, about 30 seconds per tick
- might need a larger model. one that supports tools
- its probably okay if its a little slower after its all done
- the idea is to give the llm control over the room objects,
- like:
- the neato
- the lift
- home assistant controls (they are all lights even if theyre switches)
- button box rewards, maybe the llm is allowed to add some to the counts if it decides to
- the idea is to use actual tools in ollama for it to be reliable, so need a model that supports tools.
- also, maybe using tools it could even have a small persistent memory database?
- like, maybe it can store three lines of text, and it can read these and choose which one to replace with a tool.
- the way the llm would have to act to make this fun:
- not too overbearing
- like an ominous computer, not a generic helpful assistant
- does things only when it can make them interesting
- always responds to people, doesnt always listen and obey
- doesnt talk on and on when no one wants to hear it
## for sure serious implimentation plans so far:
- replace the single "The Overseer" bot entry point in the chat system with:
- a way for services to send bot messages to the chat system through the event bus, instead of it being fully internal with the chat system.
- a simple bot: t/f flag in every chat message
- so that people who are making spectator bots can just add a new bot: true field to their message emits and show up as a bot
- keep the old overseer, don't replace it with the new llm system.
- just change it a little to use the new bot chat message stuff.
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -11,7 +11,7 @@
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="apple-mobile-web-app-title" content="Multi Roomba Rover" />
<title>Multi Roomba Rover</title>
<script type="module" crossorigin src="/assets/index-7t2kb-aG.js"></script>
<script type="module" crossorigin src="/assets/index-BhTaDZYU.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-CGvUXLso.css">
</head>
<body>
+41 -13
View File
@@ -45,21 +45,49 @@ function buildLidarRenderPoints(points = []) {
(point) => point && point.valid && Number.isFinite(point.angleDeg) && Number.isFinite(point.distanceMm),
);
const sortedPoints = [...validPoints].sort((a, b) => Number(a.angleDeg) - Number(b.angleDeg));
const filteredPoints = sortedPoints.filter((point, index, list) => {
if (list.length < 3) return true;
const distanceMm = Math.max(0, Number(point.distanceMm));
const prev = list[(index - 1 + list.length) % list.length];
const next = list[(index + 1) % list.length];
const prevDistanceMm = Math.max(0, Number(prev.distanceMm));
const nextDistanceMm = Math.max(0, Number(next.distanceMm));
const neighborDistanceMm = Math.max(prevDistanceMm, nextDistanceMm);
const groups = [];
let currentGroup = [];
// Drop single-point radial spikes that sit far beyond both adjacent angle samples.
if (neighborDistanceMm <= 0) return true;
const muchFartherThanNeighbors = distanceMm > neighborDistanceMm * 1.85;
const largeAbsoluteGap = distanceMm - neighborDistanceMm > 1400;
return !(muchFartherThanNeighbors && largeAbsoluteGap);
for (const point of sortedPoints) {
if (!currentGroup.length) {
currentGroup.push(point);
continue;
}
const previousPoint = currentGroup[currentGroup.length - 1];
const angleGap = Math.abs(Number(point.angleDeg) - Number(previousPoint.angleDeg));
const prevDistanceMm = Math.max(0, Number(previousPoint.distanceMm));
const distanceMm = Math.max(0, Number(point.distanceMm));
const distanceGap = Math.abs(distanceMm - prevDistanceMm);
if (angleGap <= 2 && distanceGap <= 900) {
currentGroup.push(point);
continue;
}
groups.push(currentGroup);
currentGroup = [point];
}
if (currentGroup.length) groups.push(currentGroup);
const groupStats = groups.map((group) => {
const distances = group.map((point) => Math.max(0, Number(point.distanceMm)));
const avgDistanceMm = distances.reduce((sum, value) => sum + value, 0) / Math.max(1, distances.length);
return {
points: group,
size: group.length,
avgDistanceMm,
};
});
const largestGroup = groupStats.reduce((best, group) => (group.size > (best?.size || 0) ? group : best), null);
const referenceDistanceMm = largestGroup?.avgDistanceMm || 1000;
const filteredPoints = groupStats
.filter((group) => {
const tinyCluster = group.size <= 3;
const farFromMainBody =
group.avgDistanceMm > referenceDistanceMm * 1.8 && group.avgDistanceMm - referenceDistanceMm > 1400;
return !(tinyCluster && farFromMainBody);
})
.flatMap((group) => group.points);
const scaleDistances = filteredPoints.map((point) => Math.max(0, Number(point.distanceMm))).sort((a, b) => a - b);
const percentileIndex = Math.max(0, Math.floor((scaleDistances.length - 1) * 0.95));
const maxDistanceMm = Math.max(1000, scaleDistances[percentileIndex] || 1000);