diff --git a/Pages/Index.cshtml b/Pages/Index.cshtml
index 908d3af..2f3ceda 100644
--- a/Pages/Index.cshtml
+++ b/Pages/Index.cshtml
@@ -259,6 +259,11 @@
|
|
+
+ |
+
+ |
+
diff --git a/wwwroot/css/app.css b/wwwroot/css/app.css
index 48dbc51..190f689 100644
--- a/wwwroot/css/app.css
+++ b/wwwroot/css/app.css
@@ -568,6 +568,12 @@ progress#revs::-webkit-progress-value {
padding: 0px;
}
+#input-graph {
+ background-color: rgba(0, 0, 0, 0.4);
+ border: 1px solid rgba(255, 255, 255, 0.2);
+ display: block;
+}
+
#steering-wheel {
width: 90px;
}
diff --git a/wwwroot/ts/hudElements/DriverInputs.ts b/wwwroot/ts/hudElements/DriverInputs.ts
index d3b7853..0db74d7 100644
--- a/wwwroot/ts/hudElements/DriverInputs.ts
+++ b/wwwroot/ts/hudElements/DriverInputs.ts
@@ -1,10 +1,13 @@
import HudElement from "./HudElement.js";
import {validNumberOrDefault, valueIsValidAssertUndefined} from "../consts.js";
import {SharedMemoryKey} from '../SharedMemoryConsumer.js';
+import {InputGraph} from "./InputGraph.js";
export default class DriverInputs extends HudElement {
override sharedMemoryKeys: SharedMemoryKey[] = ['throttleRaw', 'throttle', 'brakeRaw', 'brake', 'clutchRaw', 'clutch', 'steerInputRaw', 'steerWheelRangeDegrees'];
+ private inputGraph: InputGraph | null = null;
+
private static rawOrReal(n: number, r: number): number {
return validNumberOrDefault(n, validNumberOrDefault(r, 0));
}
@@ -19,6 +22,13 @@ export default class DriverInputs extends HudElement {
const steer = document.getElementById('steering-wheel');
+ if (!this.inputGraph) {
+ const canvas = document.getElementById('input-graph') as HTMLCanvasElement;
+ if (canvas) {
+ this.inputGraph = new InputGraph(canvas, 100);
+ }
+ }
+
tRaw = DriverInputs.rawOrReal(tRaw, t);
bRaw = DriverInputs.rawOrReal(bRaw, b);
cRaw = DriverInputs.rawOrReal(cRaw, c);
@@ -33,6 +43,10 @@ export default class DriverInputs extends HudElement {
brakeProgress.value = bRaw.toString();
clutchProgress.value = cRaw.toString();
+ if (this.inputGraph) {
+ this.inputGraph.update(tRaw, bRaw);
+ }
+
const steerAngle = sRaw * sRange / 2;
steer.style.transform = `rotate(${steerAngle}deg)`;
diff --git a/wwwroot/ts/hudElements/InputGraph.ts b/wwwroot/ts/hudElements/InputGraph.ts
new file mode 100644
index 0000000..262c709
--- /dev/null
+++ b/wwwroot/ts/hudElements/InputGraph.ts
@@ -0,0 +1,76 @@
+export class InputHistory {
+ private history: number[] = [];
+ private readonly maxSize: number;
+
+ constructor(maxSize: number) {
+ this.maxSize = maxSize;
+ }
+
+ public add(value: number): void {
+ this.history.push(value);
+ if (this.history.length > this.maxSize) {
+ this.history.shift();
+ }
+ }
+
+ public getHistory(): number[] {
+ return this.history;
+ }
+}
+
+export class InputGraph {
+ private readonly canvas: HTMLCanvasElement;
+ private readonly ctx: CanvasRenderingContext2D;
+ private readonly throttleHistory: InputHistory;
+ private readonly brakeHistory: InputHistory;
+
+ constructor(canvas: HTMLCanvasElement, historySize: number) {
+ this.canvas = canvas;
+ const context = canvas.getContext('2d');
+ if (!context) {
+ throw new Error('Could not get 2d context');
+ }
+ this.ctx = context;
+ this.throttleHistory = new InputHistory(historySize);
+ this.brakeHistory = new InputHistory(historySize);
+ }
+
+ public update(throttle: number, brake: number): void {
+ this.throttleHistory.add(throttle);
+ this.brakeHistory.add(brake);
+ this.render();
+ }
+
+ private render(): void {
+ const width = this.canvas.width;
+ const height = this.canvas.height;
+ this.ctx.clearRect(0, 0, width, height);
+
+ this.drawCurve(this.throttleHistory.getHistory(), '#00ff00'); // Green for throttle
+ this.drawCurve(this.brakeHistory.getHistory(), '#ff0000'); // Red for brake
+ }
+
+ private drawCurve(history: number[], color: string): void {
+ const historyLength = history.length;
+ if (historyLength < 2) return;
+
+ this.ctx.strokeStyle = color;
+ this.ctx.lineWidth = 2;
+ this.ctx.beginPath();
+
+ const width = this.canvas.width;
+ const height = this.canvas.height;
+ const step = width / (historyLength - 1);
+
+ for (let i = 0; i < historyLength; i++) {
+ const x = i * step;
+ const y = height - (history[i] * height);
+ if (i === 0) {
+ this.ctx.moveTo(x, y);
+ } else {
+ this.ctx.lineTo(x, y);
+ }
+ }
+ this.ctx.stroke();
+ }
+}