Compare commits

..

8 Commits

Author SHA1 Message Date
0c5775560c improved makefile 2023-04-08 03:43:23 +02:00
a1fdca689f updated README 2023-04-08 03:42:10 +02:00
b9fcbd9040 fixed GPS 2023-04-08 03:41:52 +02:00
ba05ff7645 added distance to Pos3 2023-04-08 03:41:43 +02:00
14f7b6c6df added shutdown 2023-04-08 00:39:54 +02:00
f8f5f5e5c7 try catch in entrypoint for kernel stuff 2023-04-01 03:27:52 +02:00
bf378deea2 moved log trigger before printWeb 2023-04-01 03:27:17 +02:00
df39865c3d added round to Pos3 2023-04-01 03:26:42 +02:00
10 changed files with 109 additions and 72 deletions

View File

@@ -5,6 +5,7 @@ BUILD_DIR = build
HAXE_FLAGS =
POLYFILLED_NAME = bundle.polyfill.lua
POLYFILL_SRC = src/polyfill.lua
CREAFTOS_PATH = craftos
HAXE_PATH := $(BUILD_DIR)/$(HAXE_NAME)
MIN_PATH := $(BUILD_DIR)/$(MINIFYD_NAME)
@@ -12,31 +13,38 @@ POLYFILL_PATH := $(BUILD_DIR)/$(POLYFILLED_NAME)
all: clean build
build: HAXE_FLAGS += --main kernel.Entrypoint -D analyzer-optimize
build: $(MIN_PATH)
debug: HAXE_FLAGS += -D webconsole -D error_stack --debug
debug: build
$(HAXE_PATH): $(shell find src -name '*.hx')
haxe build.hxml $(HAXE_FLAGS) --cmd "mv build/_haxe.lua $(HAXE_PATH)"
$(MIN_PATH): $(POLYFILL_PATH)
node minify.js $(POLYFILL_PATH) $@
haxe build.hxml $(HAXE_FLAGS)
$(POLYFILL_PATH): $(POLYFILL_SRC) $(HAXE_PATH)
cat $(POLYFILL_SRC) $(HAXE_PATH) > $@
deps: package.json build.hxml
$(MIN_PATH): $(POLYFILL_PATH)
node minify.js $(POLYFILL_PATH) $@
.PHONY: deps
deps:
haxelib install all --always && yarn install
.PHONY: clean
clean:
rm -rf $(BUILD_DIR)
mkdir $(BUILD_DIR)
.PHONY: watch
watch:
find src -name "*.hx" | entr make debug
.PHONY: emulator
emulator:
craftos --mount-ro /=build
$(CREAFTOS_PATH) --mount-ro /=$(shell pwd)/$(BUILD_DIR)
.PHONY: webconsole
webconsole:
node console.js

View File

@@ -21,7 +21,7 @@ run `make deps && make`. The `bundle.min.lua` inside the `build` dir is the fina
# Useful links
[CC lua code](https://github.com/cc-tweaked/CC-Tweaked/tree/mc-1.16.x/src/main/resources/data/computercraft/lua)
[CC lua code](https://github.com/cc-tweaked/CC-Tweaked/tree/mc-1.19.x/projects/core/src/main/resources/data/computercraft/lua)
[CC wiki](https://tweaked.cc/)
@@ -38,6 +38,7 @@ Run `make watch` to recompile when a file changed.
## Emulator
You could use Minecraft to run the program or you could use [craftos pc](https://www.craftos-pc.cc/) as an emulator. Just install it and run `make emulator`.
There is an AppImage available [here](https://github.com/MCJack123/craftos2/releases).
## Websconsole

View File

@@ -1,5 +1,4 @@
-p src
--main kernel.Entrypoint
--library cctweaked:git:https://git.kapelle.org/niklas/cctweaked-haxelib.git
--library tink_core
@@ -9,4 +8,4 @@
-D lua-vanilla
-D lua-ver 5.1
--lua build/_haxe.lua
--lua build/haxe.lua

View File

@@ -4,7 +4,13 @@ import kernel.log.Log;
class Entrypoint {
public static function main() {
try {
Init.initKernel();
}catch(e){
Log.error('Error in init: ${e.toString()}');
return;
}
try {
Startup.main();
}catch(e){

View File

@@ -13,6 +13,10 @@ import kernel.peripherals.Peripherals.Peripheral;
import kernel.net.Net;
class Init {
@:allow(kernel.KernelEvents)
private static var mainEvent:MainEvent;
public static function initKernel() {
// Init singeltons here because haxe is confused about the order to create them.
Log.instance = new Log();
@@ -44,9 +48,8 @@ class Init {
FS.makeDir("/var/ns");
}
MainLoop.add(()->{
Init.mainEvent = MainLoop.add(()->{
KernelEvents.instance.startEventLoop();
});
}
}

View File

@@ -1,11 +1,12 @@
package kernel;
import haxe.MainLoop;
import cc.OS;
import kernel.log.Log;
import lib.Pos;
import cc.HTTP.HTTPResponse;
import lua.TableTools;
import lua.Coroutine;
import lib.Vec.Vec2;
import haxe.Exception;
using tink.CoreApi;
@@ -95,6 +96,8 @@ class KernelEvents {
private final onWebsocketMessageTrigger:SignalTrigger<{url:String, message:String, isBinary:Bool}> = Signal.trigger();
private final onWebsocketSuccessTrigger:SignalTrigger<{url:String, handle:Any}> = Signal.trigger();
private var stopLoop:Bool = false;
@:allow(kernel.Init)
private function new() {
this.onAlarm = onAlarmTrigger.asSignal();
@@ -132,15 +135,26 @@ class KernelEvents {
/**
Start pulling events. Blocking.
**/
public function startEventLoop() {
while (true) {
@:allow(kernel.Init)
private function startEventLoop() {
while (!stopLoop) {
var event:Table<Int, Dynamic> = pullEvents();
var eventName:String = event[1];
try {
fireSignal(eventName,event);
}catch(e:Dynamic) {
Log.error('Error while handling event: $eventName: ${e}');
}
}
}
public function shutdown() {
Log.info('Shutting down event loop');
this.stopLoop = true;
MainTerm.instance.reset();
Init.mainEvent.stop();
}
private function pullEvents():Table<Int, Dynamic> {
return cast TableTools.pack(Coroutine.yield(null));

View File

@@ -1,11 +1,14 @@
package kernel.gps;
import kernel.log.Log;
import lib.KVStore;
import kernel.net.Net;
import kernel.net.INetworkInterface;
import kernel.net.Package;
import lib.Pos3;
using tink.CoreApi;
/**
Determines the position of the computer based on the distance to other computers.
When receiving a message from another computer via wireless, the distance is also received.
@@ -15,6 +18,7 @@ class GPS {
public static var instance:GPS;
private var shouldRespond = true;
private var shouldDoWholeNumberCheck = true;
private var posAccuracy = 0; // 0 = unkown, 1 = (ins,best guess), 2 = (stored/manual,should be right), 3 = (gps,confirmed)
private var cachedPosition:Pos3;
private var lastPositionResponse: Array<{pos:Pos3,dist:Float}> = [];
@@ -112,12 +116,18 @@ class GPS {
var response = new Package(Net.instance.networkID,pack.fromID, pack.msgID, GPSResponse(cachedPosition),null,0);
iface.send(pack.fromID,Net.instance.networkID,response);
case GPSResponse(pos):
if (lastPositionResponse.contains({pos:pos,dist:dist})) return;
lastPositionResponse.push({pos:pos,dist:dist});
if (lastPositionResponse.length > 5) lastPositionResponse.shift();
if (lastPositionResponse.length < 3) return;
if (lastPositionResponse.contains({pos:pos,dist:dist})) return; // Ignore duplicate responses
lastPositionResponse.push({pos:pos,dist:dist});
// TODO: wait for a few seconds before calculating the position, so we can get more responses
if (lastPositionResponse.length < 4) return; // We need at least 3 responses to calculate the position
var calculatedPosition = calculatePosition().round();
lastPositionResponse = []; // Reset the response array
var calculatedPosition = calculatePosition();
if (calculatedPosition == null) return;
cachedPosition = calculatedPosition;
posAccuracy = 3;
@@ -137,62 +147,46 @@ class GPS {
var r2 = lastPositionResponse[1].dist;
var r3 = lastPositionResponse[2].dist;
return trilateration(p1,p2,p3,r1,r2,r3);
var result = trilateration(p1,p2,p3,r1,r2,r3);
// var calculatedPositions: Array<Pos3> = [];
if (result.a.close(result.b)) return result.a;
// // Loop through all possible permutations of the last 3 responses
// for (i in 0...lastPositionResponse.length) {
// for (j in 0...lastPositionResponse.length) {
// if (i == j) continue;
// for (k in 0...lastPositionResponse.length) {
// if (i == k || j == k) continue;
// If we have more than 3 responses, we can use the 4th response to determine which of the two positions is correct
// TODO: if this is a pocket computer we cant use this since it can move freely
if (lastPositionResponse.length > 3){
var err1 = Math.abs(result.a.distance(lastPositionResponse[3].pos) - lastPositionResponse[3].dist);
var err2 = Math.abs(result.b.distance(lastPositionResponse[3].pos) - lastPositionResponse[3].dist);
// var p1 = lastPositionResponse[i].pos;
// var p2 = lastPositionResponse[j].pos;
// var p3 = lastPositionResponse[k].pos;
// var r1 = lastPositionResponse[i].dist;
// var r2 = lastPositionResponse[j].dist;
// var r3 = lastPositionResponse[k].dist;
// calculatedPositions.push(trilateration(p1,p2,p3,r1,r2,r3));
// }
// }
// }
// var tainted = false;
// // Check if all calculated positions are the same
// for (i in 0...calculatedPositions.length) {
// for (j in 0...calculatedPositions.length) {
// if (i == j) continue;
// if (calculatedPositions[i] != calculatedPositions[j]){
// Log.warn("GPS not all calculated positions are the same");
// tainted = true;
// }
// }
// }
// if (!tainted) return calculatedPositions[0];
// // Get the most common position
// var mostCommon:Pos3 = null;
// var mostCommonCount = 0;
// for (i in 0...calculatedPositions.length) {
// var count = 0;
// for (j in 0...calculatedPositions.length) {
// if (calculatedPositions[i] == calculatedPositions[j]) count++;
// }
// if (count > mostCommonCount) {
// mostCommon = calculatedPositions[i];
// mostCommonCount = count;
// }
// }
// return mostCommon;
if (Math.abs(err1 - err2) < 0.0001) {
Log.warn("Failed to determine GPS position via 4th fix");
return null; // The two positions are essentially the same, so we cant determine which one is correct
}
private function trilateration(p1:Pos3,p2:Pos3,p3: Pos3,r1:Float,r2:Float,r3:Float):Pos3 {
if (err1 < err2) return result.a;
if (err2 < err1) return result.b;
}
// last resort, just use the position that is closest to a whole number (whithin a resonable margin of error)
if (!shouldDoWholeNumberCheck) return null;
// TODO: mark the position as not so accurate if we use this method
var err1 = (result.a - result.a.round()).length();
var err2 = (result.b - result.b.round()).length();
if (err1 < err2 && err1 < 0.0001) {
return result.a;
} else if (err2 < 0.0001) {
return result.b;
}
return null;
}
/**
Determines the position(s) of a point given 3 other points and the distance to each of them.
**/
private function trilateration(p1:Pos3,p2:Pos3,p3: Pos3,r1:Float,r2:Float,r3:Float):Pair<Pos3,Pos3> {
var a2b = p2 - p1;
var a2c = p3 - p1;
@@ -211,9 +205,9 @@ class GPS {
var zSquared = r1 * r1 - x * x - y * y;
if (zSquared > 0) {
var z = Math.sqrt(zSquared);
result += ez * z;
return new Pair(result + (ez * z),result - (ez * z));
}
return result;
return new Pair(result,result);
}
}

View File

@@ -53,12 +53,11 @@ class Log {
if (logLines.length > MAX_LINES) {
logLines.shift();
}
onLogTrigger.trigger(line);
#if webconsole
Debug.printWeb('[${Std.string(line.level)}][${line.origin}] ${line.message}');
#end
onLogTrigger.trigger(line);
}
public function getLines():ReadOnlyArray<LogLine> {

View File

@@ -130,6 +130,7 @@ class HomeContext {
children.push(new TextElement('Add Terminal', {onClick: this.addTerminal}));
children.push(new TextElement('Add Log', {onClick: this.addLog}));
children.push(new TextElement('Exit', {onClick: KernelEvents.instance.shutdown}));
renderer.setChildren(children);

View File

@@ -96,4 +96,16 @@ abstract Pos3(Vec3<Float>) from Vec3<Float> to Vec3<Float>{
public function toString():String {
return 'Pos3(${this.x}, ${this.y}, ${this.z})';
}
public function round():Pos3 {
return new Pos3({
x: Math.fround(this.x),
y: Math.fround(this.y),
z: Math.fround(this.z)
});
}
public function distance(rhs:Pos3):Float {
return Math.sqrt(Math.pow(this.x - rhs.x, 2) + Math.pow(this.y - rhs.y, 2) + Math.pow(this.z - rhs.z, 2));
}
}