Skip to content

Commit

Permalink
finalize recorder.
Browse files Browse the repository at this point in the history
  • Loading branch information
ckeller81 committed Aug 24, 2024
1 parent 9795a8f commit 7a395ba
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 54 deletions.
12 changes: 10 additions & 2 deletions src/assets/base.css
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,6 @@
*::after {
box-sizing: border-box;
margin: 0;
font-weight: normal;
font-size: 14px;
}

body {
Expand Down Expand Up @@ -85,3 +83,13 @@ body {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}

p {
font-weight: normal;
font-size: 14px;
margin-bottom: .1rem;
}

h1, h2, h3, h4, h5, h6 {
margin: 0 0 .3rem;
}
7 changes: 5 additions & 2 deletions src/services/device-position-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export class DevicePositionService {
alpha: 0,
beta: 0,
gamma: 0,
},
}
};

// Kalman filters for each axis
Expand Down Expand Up @@ -123,6 +123,9 @@ export class DevicePositionService {
this._positionChange.x = (this._currentSpeed.x * deltaTime) * (180 / Math.PI) * earthRadius;
this._positionChange.y = (this._currentSpeed.y * deltaTime) * (180 / Math.PI) * earthRadius;
this._positionChange.z = (this._currentSpeed.z * deltaTime) * (180 / Math.PI) * earthRadius;

// Notify observers of the updated position change
this.notifyObservers();
}
}

Expand Down Expand Up @@ -150,7 +153,7 @@ export class DevicePositionService {
alpha: 0,
beta: 0,
gamma: 0,
},
}
};

this.notifyObservers();
Expand Down
15 changes: 8 additions & 7 deletions src/services/websocket-service.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@

import type { CreateTrackNodeModel } from "@/models/create-track-node-model";
import type { DevicePositionModel } from "@/models/device-position-model";
import type { TrackNodeModel } from "@/models/track-node-model";
import type { UploadPictureModel } from "@/models/upload-picture-model";
import * as signalR from "@microsoft/signalr";
Expand All @@ -24,27 +25,27 @@ export class WebSocketService {
await this._trackNodeHub?.stop();
}

async trackNode(previousTrackNodeId: string | null, lat: number, lon: number, alt: number, image: UploadPictureModel) {
async trackNode(previousTrackNodeId: string | null, geoPosition: { latitude: number; longitude: number; altitude: number }, devicePosition: DevicePositionModel, image: UploadPictureModel) {
if (!this._trackNodeHub || this._trackNodeHub.state !== signalR.HubConnectionState.Connected) {
throw new Error("The WebSocket connection is not yet established.");
}

const createTrackNodeModel: CreateTrackNodeModel = {
previousTrackNodeId: previousTrackNodeId,
Location: {
latitude: lat,
longitude: lon,
altitude: alt
latitude: geoPosition.latitude,
longitude: geoPosition.longitude,
altitude: geoPosition.altitude
},
Vector: {
x: 0,
y: 0,
z: 0
},
Orientation: {
alpha: 0,
beta: 0,
gamma: 0
alpha: devicePosition?.orientation.alpha ?? 0,
beta: devicePosition?.orientation.beta ?? 0,
gamma: devicePosition?.orientation.gamma ?? 0
}
};

Expand Down
140 changes: 97 additions & 43 deletions src/views/HomeView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,39 @@
<main class="main">
<canvas id="video" class="video-container" width="640" height="480"></canvas>
<div class="overlay">
<p>LatLong: {{ position.latitude.toFixed(6) }} / {{ position.longitude.toFixed(6) }}</p>
<p>Altitude: {{ position.altitude.toFixed(2) }}</p>
<p>Last update: {{ lastUpdate }}</p>
<p v-if="lastError">Error: {{ lastError }}</p>
<button v-if="!devicePositionEnabled" @click="enableDevicePosition">Enable Device Position</button>
<div v-else>
<p>Device-Position:</p>
<p>x: {{ devicePosition.x.toFixed(2) }}</p>
<p>y: {{ devicePosition.y.toFixed(2) }}</p>
<p>z: {{ devicePosition.z.toFixed(2) }}</p>
<p>Orientation:</p>
<p>alpha: {{ devicePosition.orientation.alpha.toFixed(2) }}</p>
<p>beta: {{ devicePosition.orientation.beta.toFixed(2) }}</p>
<p>gamma: {{ devicePosition.orientation.gamma.toFixed(2) }}</p>
<p>Last update: {{ lastUpdateDevicePosition }}</p>
<button @click="resetDevicePosition">Reset Device Position</button>
<div class="container">
<h5>GPS Position</h5>
<p>LatLong: {{ position.latitude.toFixed(6) }} / {{ position.longitude.toFixed(6) }}</p>
<p>Altitude: {{ position.altitude.toFixed(2) }}</p>
<p>Last update: {{ lastUpdate }}</p>
<button v-if="!devicePositionEnabled" @click="enableDevicePosition">Enable Device Position</button>
<div v-else>
<h5>Device-Position:</h5>
<p>x: {{ devicePosition.x.toFixed(2) }}</p>
<p>y: {{ devicePosition.y.toFixed(2) }}</p>
<p>z: {{ devicePosition.z.toFixed(2) }}</p>
<h5>Orientation:</h5>
<p>&alpha;: {{ devicePosition.orientation.alpha.toFixed(2) }} | &beta;: {{ devicePosition.orientation.beta.toFixed(2) }} | &gamma;: {{ devicePosition.orientation.gamma.toFixed(2) }}</p>
<p>Last update: {{ lastUpdateDevicePosition }}</p>
</div>
<h5>Recorded track</h5>
<p>Track-Uploads: {{ succeededUploads }} ok, {{ failedUploads }} failed, {{ ignoredUploads }} ignored</p>
<p v-if="lastError">Error: {{ lastError }}</p>

<div class="button-list">
<button @click="toggleEnableUpload"><template v-if="uploadEnabled">Disable upload</template><template v-else>Enable upload</template></button>
<button @click="triggerUpload">Trigger Upload</button>
<button v-if="devicePositionEnabled" @click="resetDevicePosition">Reset Device Position</button>
</div>
<canvas id="transmitted" class="transmit-container" width="256" height="256"></canvas>
</div>
<button @click="startNewDevicePosition">Start new Device Position</button>
<p>NewPosition: {{ newPosition }}</p>
<p>Track-Uploads: {{ succeededUploads }} ok, {{ failedUploads }} failed</p>
<button @click="triggerUpload">Trigger Upload</button>
<canvas id="transmitted" class="transmit-container" width="256" height="256"></canvas>
</div>
</main>
</template>

<script lang="ts">
import type { DevicePositionModel } from "@/models/device-position-model";
import type { TrackNodeModel } from "@/models/track-node-model";
import { DeviceMovementTracker } from "@/services/device-movement-tracker";
import { DevicePositionService } from "@/services/device-position-service";
import { ImageCaptureService } from "@/services/image-capture-service";
import { PositionService } from "@/services/position-service";
Expand Down Expand Up @@ -69,10 +72,11 @@ export default defineComponent({
const lastUpdateDevicePosition = ref("");
const succeededUploads = ref(0);
const failedUploads = ref(0);
const ignoredUploads = ref(0);
const devicePositionEnabled = ref(false);
const newPosition = ref("");
const lastError = ref("");
const isUploadInProgress = ref(false);
const uploadEnabled = ref(false);
const uploadData = async () => {
if (isUploadInProgress.value) {
Expand All @@ -83,13 +87,20 @@ export default defineComponent({
try {
isUploadInProgress.value = true;
const image = imageCaptureService.extractImage();
if (uploadEnabled.value) {
previousNode.value = await webSocketService.trackNode(previousNode.value?.id ?? null, position.value, devicePosition.value, image);
}
const transmittedImage = document.getElementById("transmitted") as HTMLCanvasElement;
const context = transmittedImage.getContext("2d")
context!.putImageData(image.imageData!, 0, 0);
delete image.imageData;
previousNode.value = await webSocketService.trackNode(previousNode.value?.id ?? null, position.value.latitude, position.value.longitude, position.value.altitude, image);
succeededUploads.value++;
if (uploadEnabled.value) {
succeededUploads.value++;
} else {
ignoredUploads.value++;
}
} catch (error: any) {
console.error(error);
failedUploads.value++;
Expand Down Expand Up @@ -122,25 +133,14 @@ export default defineComponent({
await devicePositionService.resetPosition();
}
const startNewDevicePosition = async () => {
try {
const deviceMovementService = new DeviceMovementTracker();
await deviceMovementService.requestAccess();
deviceMovementService.startTracking();
setInterval(() => {
const pos = deviceMovementService.position;
newPosition.value = `x: ${pos.x.toFixed(2)}, y: ${pos.y.toFixed(2)}, z: ${pos.z.toFixed(2)}`;
})
} catch (error) {
alert(error);
}
}
const triggerUpload = async () => {
uploadData();
}
const toggleEnableUpload = () => {
uploadEnabled.value = !uploadEnabled.value;
}
onMounted(async () => {
const video = document.getElementById("video") as HTMLCanvasElement;
imageCaptureService = new ImageCaptureService(video);
Expand All @@ -155,6 +155,7 @@ export default defineComponent({
});
return {
uploadEnabled,
devicePositionEnabled,
position,
devicePosition,
Expand All @@ -163,11 +164,11 @@ export default defineComponent({
lastError,
succeededUploads,
failedUploads,
newPosition,
startNewDevicePosition,
ignoredUploads,
enableDevicePosition,
resetDevicePosition,
triggerUpload
triggerUpload,
toggleEnableUpload
};
},
methods: {
Expand Down Expand Up @@ -195,11 +196,64 @@ export default defineComponent({
z-index: 1;
}
.container {
width: 50vw;
display: flex;
flex-direction: column;
justify-content: center;
}
.container p {
width: 100%;
text-align: left;
}
.transmit-container {
width: 256px;
height: 256px;
margin: 20px auto;
}
@media (max-width: 768px) {
.container {
width: 90vw;
}
}
.video-container {
position: absolute;
width: 100%;
height: 100%;
z-index: 0;
}
.button-list {
display: flex;
flex-direction: row;
justify-content: stretch;
margin-top: 20px;
}
.button-list button {
padding: 10px;
font-size: .7rem;
background-color: #007bff;
color: white;
border: none;
border-radius: 0;
cursor: pointer;
}
.button-list button:first-child {
background-color: #28a745;
border-top-left-radius: 5px;
border-bottom-left-radius: 5px;
}
.button-list button:last-child {
background-color: #dc3545;
border-top-right-radius: 5px;
border-bottom-right-radius: 5px;
}
</style>

0 comments on commit 7a395ba

Please sign in to comment.