Compare commits
8 Commits
4a7b57c47f
...
0c5775560c
| Author | SHA1 | Date | |
|---|---|---|---|
| 0c5775560c | |||
| a1fdca689f | |||
| b9fcbd9040 | |||
| ba05ff7645 | |||
| 14f7b6c6df | |||
| f8f5f5e5c7 | |||
| bf378deea2 | |||
| df39865c3d |
22
Makefile
22
Makefile
@@ -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: 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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -4,7 +4,13 @@ import kernel.log.Log;
|
||||
|
||||
class Entrypoint {
|
||||
public static function main() {
|
||||
Init.initKernel();
|
||||
try {
|
||||
Init.initKernel();
|
||||
}catch(e){
|
||||
Log.error('Error in init: ${e.toString()}');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
Startup.main();
|
||||
}catch(e){
|
||||
|
||||
@@ -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();
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,16 +135,27 @@ 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];
|
||||
|
||||
fireSignal(eventName,event);
|
||||
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));
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
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
|
||||
}
|
||||
|
||||
// var r1 = lastPositionResponse[i].dist;
|
||||
// var r2 = lastPositionResponse[j].dist;
|
||||
// var r3 = lastPositionResponse[k].dist;
|
||||
if (err1 < err2) return result.a;
|
||||
if (err2 < err1) return result.b;
|
||||
}
|
||||
|
||||
// calculatedPositions.push(trilateration(p1,p2,p3,r1,r2,r3));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// last resort, just use the position that is closest to a whole number (whithin a resonable margin of error)
|
||||
if (!shouldDoWholeNumberCheck) return null;
|
||||
|
||||
// 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;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// TODO: mark the position as not so accurate if we use this method
|
||||
|
||||
// if (!tainted) return calculatedPositions[0];
|
||||
var err1 = (result.a - result.a.round()).length();
|
||||
var err2 = (result.b - result.b.round()).length();
|
||||
|
||||
// // 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;
|
||||
// }
|
||||
// }
|
||||
if (err1 < err2 && err1 < 0.0001) {
|
||||
return result.a;
|
||||
} else if (err2 < 0.0001) {
|
||||
return result.b;
|
||||
}
|
||||
|
||||
// return mostCommon;
|
||||
return null;
|
||||
}
|
||||
|
||||
private function trilateration(p1:Pos3,p2:Pos3,p3: Pos3,r1:Float,r2:Float,r3:Float):Pos3 {
|
||||
/**
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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> {
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user