@robotical/webapp-types 3.25.8 → 3.25.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-types/package.json +1 -1
- package/dist-types/src/application/RAFTs/Marty/PublishedDataAnalyser.d.ts +3 -1
- package/dist-types/src/application/RAFTs/Marty/PublishedDataAnalyser.js +6 -2
- package/dist-types/src/components/disposables/buttons/SimpleButton/index.d.ts +2 -1
- package/dist-types/src/components/disposables/buttons/SimpleButton/index.js +2 -2
- package/dist-types/src/components/oneoffs/calibration-screens/ColourSensorCalibration/messages.d.ts +5 -3
- package/dist-types/src/components/oneoffs/calibration-screens/ColourSensorCalibration/messages.js +5 -3
- package/dist-types/src/screens/configuration/marty/Diagnostics/ColourSensorDiagnostics/messages.d.ts +4 -0
- package/dist-types/src/screens/configuration/marty/Diagnostics/ColourSensorDiagnostics/messages.js +4 -0
- package/dist-types/src/utils/colour-classifier.d.ts +10 -0
- package/dist-types/src/utils/colour-classifier.js +54 -1
- package/dist-types/src/utils/colour-sensor-diagnostics.d.ts +8 -1
- package/dist-types/src/utils/colour-sensor-diagnostics.js +2 -1
- package/dist-types/src/utils/colour-sensor-registers.js +5 -2
- package/dist-types/src/utils/marty-colour-policy.json +2 -1
- package/package.json +1 -1
package/dist-types/package.json
CHANGED
|
@@ -6,6 +6,8 @@ import type { RICStateInfo } from "@robotical/roboticaljs";
|
|
|
6
6
|
import { type ColourSensorValues } from "./published-data-helpers";
|
|
7
7
|
interface MartyState {
|
|
8
8
|
colourSensed: "blue" | "green" | "red" | "yellow" | "purple" | "unclear" | "air";
|
|
9
|
+
/** Rule strength (0–100), not probability; null when no scored reading is available. */
|
|
10
|
+
colourConfidence: number | null;
|
|
9
11
|
lightSense: "none" | "high" | "mid" | "low";
|
|
10
12
|
objectSense: "none" | "near";
|
|
11
13
|
noiseSense: "none" | "detected";
|
|
@@ -34,7 +36,7 @@ declare class PublishedDataAnalyser extends EventEmitter {
|
|
|
34
36
|
subscribeToPublishedData(): void;
|
|
35
37
|
unsubscribeFromPublishedData(): void;
|
|
36
38
|
analyse(data: RICStateInfo): void;
|
|
37
|
-
setColourSensed(colour: MartyState["colourSensed"]): void;
|
|
39
|
+
setColourSensed(colour: MartyState["colourSensed"], confidence?: number | null): void;
|
|
38
40
|
setLightSense(lightSense: MartyState["lightSense"]): void;
|
|
39
41
|
setObjectSense(objectSense: MartyState["objectSense"]): void;
|
|
40
42
|
setNoiseSense(noiseSense: MartyState["noiseSense"]): void;
|
|
@@ -61,6 +61,7 @@ var PublishedDataAnalyser = /** @class */ (function (_super) {
|
|
|
61
61
|
_this.marty = marty;
|
|
62
62
|
_this.martyState = {
|
|
63
63
|
colourSensed: "unclear",
|
|
64
|
+
colourConfidence: null,
|
|
64
65
|
lightSense: "none",
|
|
65
66
|
objectSense: "none",
|
|
66
67
|
noiseSense: "none",
|
|
@@ -101,8 +102,10 @@ var PublishedDataAnalyser = /** @class */ (function (_super) {
|
|
|
101
102
|
this.connectedSensors.objectSensor = !!objectSensor || !!colourSensor;
|
|
102
103
|
this.connectedSensors.noiseSensor = !!noiseSensor;
|
|
103
104
|
};
|
|
104
|
-
PublishedDataAnalyser.prototype.setColourSensed = function (colour) {
|
|
105
|
+
PublishedDataAnalyser.prototype.setColourSensed = function (colour, confidence) {
|
|
106
|
+
if (confidence === void 0) { confidence = null; }
|
|
105
107
|
this.martyState.colourSensed = colour;
|
|
108
|
+
this.martyState.colourConfidence = confidence;
|
|
106
109
|
this.emit(this.eventsMap.colourSensed[colour]);
|
|
107
110
|
};
|
|
108
111
|
PublishedDataAnalyser.prototype.setLightSense = function (lightSense) {
|
|
@@ -124,7 +127,8 @@ var ColourSensedDetection = /** @class */ (function () {
|
|
|
124
127
|
}
|
|
125
128
|
ColourSensedDetection.prototype.detectColourSensed = function (_a, analyser, profile) {
|
|
126
129
|
var r = _a.r, g = _a.g, b = _a.b, clear = _a.clear, air = _a.air;
|
|
127
|
-
|
|
130
|
+
var reading = classifyColour({ red: r, green: g, blue: b, clear: clear, air: air }, profile);
|
|
131
|
+
return analyser.setColourSensed(reading.classifiedColour, reading.confidence);
|
|
128
132
|
};
|
|
129
133
|
return ColourSensedDetection;
|
|
130
134
|
}());
|
|
@@ -11,6 +11,7 @@ type SimpleButtonProps = {
|
|
|
11
11
|
textColour?: string;
|
|
12
12
|
ariaLabel?: string;
|
|
13
13
|
buttonType?: "button" | "submit" | "reset";
|
|
14
|
+
className?: string;
|
|
14
15
|
};
|
|
15
|
-
export default function SimpleButton({ onClick, title, titleSize, disabled, colour, otherStyles, borderColour, textColour, ariaLabel, buttonType, }: SimpleButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
16
|
+
export default function SimpleButton({ onClick, title, titleSize, disabled, colour, otherStyles, borderColour, textColour, ariaLabel, buttonType, className, }: SimpleButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
16
17
|
export {};
|
|
@@ -87,8 +87,8 @@ var getAccessibleTextColour = function (backgroundColour) {
|
|
|
87
87
|
return blackContrast >= whiteContrast ? BLACK : WHITE;
|
|
88
88
|
};
|
|
89
89
|
export default function SimpleButton(_a) {
|
|
90
|
-
var onClick = _a.onClick, title = _a.title, titleSize = _a.titleSize, disabled = _a.disabled, colour = _a.colour, otherStyles = _a.otherStyles, borderColour = _a.borderColour, textColour = _a.textColour, ariaLabel = _a.ariaLabel, _b = _a.buttonType, buttonType = _b === void 0 ? "button" : _b;
|
|
90
|
+
var onClick = _a.onClick, title = _a.title, titleSize = _a.titleSize, disabled = _a.disabled, colour = _a.colour, otherStyles = _a.otherStyles, borderColour = _a.borderColour, textColour = _a.textColour, ariaLabel = _a.ariaLabel, _b = _a.buttonType, buttonType = _b === void 0 ? "button" : _b, _c = _a.className, className = _c === void 0 ? "" : _c;
|
|
91
91
|
var resolvedTextColour = textColour || getAccessibleTextColour(colour);
|
|
92
92
|
return (_jsx("button", __assign({ type: buttonType, className: "simple-button-component " +
|
|
93
|
-
(disabled ? "simple-button-component-disabled" : ""), disabled: disabled, "aria-label": ariaLabel, style: __assign(__assign({}, otherStyles), { fontSize: titleSize, backgroundColor: colour, border: borderColour && "1px solid ".concat(borderColour), color: resolvedTextColour }), onClick: onClick }, { children: title })));
|
|
93
|
+
(disabled ? "simple-button-component-disabled" : "") + " " + className, disabled: disabled, "aria-label": ariaLabel, style: __assign(__assign({}, otherStyles), { fontSize: titleSize, backgroundColor: colour, border: borderColour && "1px solid ".concat(borderColour), color: resolvedTextColour }), onClick: onClick }, { children: title })));
|
|
94
94
|
}
|
package/dist-types/src/components/oneoffs/calibration-screens/ColourSensorCalibration/messages.d.ts
CHANGED
|
@@ -6,13 +6,14 @@ declare const english: {
|
|
|
6
6
|
readonly uploadPending: "Some calibration data is waiting to upload. It is saved on this device and will retry automatically when the connection is available.";
|
|
7
7
|
readonly uploadStorageWarning: "Some calibration data could not be saved on this device yet. Keep the app open and retry uploading before closing it.";
|
|
8
8
|
readonly phoneUploadPending: "Calibration data is waiting to upload. Keep the app open until uploading finishes so these readings are not lost.";
|
|
9
|
+
readonly phoneUploadsAutomatic: "Calibration readings upload automatically under this session ID. Keep the app open while calibrating.";
|
|
9
10
|
readonly retryUpload: "Retry calibration upload";
|
|
10
11
|
readonly introduction: "Keep Marty connected to USB power. We will collect {{count}} readings each for air and white, then save the calibration. Keep the lighting the same throughout.";
|
|
11
12
|
readonly sensor: "Colour sensor";
|
|
12
13
|
readonly selectSensor: "Select a colour sensor";
|
|
13
14
|
readonly selectReplacementSensor: "The sensor selected in diagnostics is no longer attached. Select the colour sensor you want to calibrate.";
|
|
14
15
|
readonly step: "Step {{number}} of 2";
|
|
15
|
-
readonly air: "Lift Marty about 30 cm above the surface with both feet clear. Hold it steady and capture the air readings.";
|
|
16
|
+
readonly air: "Leave USB power connected. Lift Marty about 30 cm above the surface with both feet clear. Hold it steady and capture the air readings.";
|
|
16
17
|
readonly white: "Place the foot with the selected colour sensor flat on a matt white surface, with the sensor fully over it. Hold Marty steady and capture the white readings.";
|
|
17
18
|
readonly duration: "Each capture takes about 3–4 seconds once sampling starts. Preparing or restoring sensor settings can take a few extra seconds.";
|
|
18
19
|
readonly preparing: "Preparing the sensor…";
|
|
@@ -30,8 +31,8 @@ declare const english: {
|
|
|
30
31
|
readonly calibrationRequired: "Calibrate the colour sensor";
|
|
31
32
|
readonly saved: "Calibration saved on Marty: {{count}} readings each for air and white.";
|
|
32
33
|
readonly reconnectStep: "Final step: reconnect Marty";
|
|
33
|
-
readonly reconnect: "Disconnect
|
|
34
|
-
readonly disconnectToFinish: "Disconnect
|
|
34
|
+
readonly reconnect: "Leave the USB cable plugged in. Use Disconnect in app below, then use Connect Marty to connect the same robot again. Your calibration is saved. Colour diagnostics will unlock once Marty has loaded the new sensor settings.";
|
|
35
|
+
readonly disconnectToFinish: "Disconnect in app";
|
|
35
36
|
readonly disconnecting: "Disconnecting Marty…";
|
|
36
37
|
readonly loadingCalibration: "Marty has reconnected. Waiting for the new sensor settings and fresh readings…";
|
|
37
38
|
readonly calibrationCheckDelayed: "Marty is connected, but the sensor check is taking longer than expected. The app is retrying automatically. Keep the sensor attached and Marty on USB power. If this continues, disconnect and reconnect Marty.";
|
|
@@ -46,6 +47,7 @@ declare const english: {
|
|
|
46
47
|
readonly notInAir: "Lift Marty so both feet are clear of the surface, then try again.";
|
|
47
48
|
readonly sensorDisconnected: "Connect and verify Marty, with its colour sensor attached, to continue.";
|
|
48
49
|
readonly unsupported: "This sensor or app connection does not support the new calibration yet. Update the app and reconnect Marty. Supported colour sensor firmware: type 97 / 1.3.1 and type 98 / 1.4.0–1.4.1.";
|
|
50
|
+
readonly sensorInitialising: "The colour sensor is still getting ready. Keep Marty connected, wait a few seconds and try this step again.";
|
|
49
51
|
readonly readFailed: "A sensor reading could not be collected. Keep Marty connected and try this step again.";
|
|
50
52
|
readonly unstable: "The readings varied too much. Keep Marty steady and the lighting constant, then capture this position again.";
|
|
51
53
|
readonly saturated: "The air readings reached the sensor's limit of 255. Lift Marty clear of the surface and keep it away from direct bright light, then retry. No new calibration was saved.";
|
package/dist-types/src/components/oneoffs/calibration-screens/ColourSensorCalibration/messages.js
CHANGED
|
@@ -6,13 +6,14 @@ var english = {
|
|
|
6
6
|
uploadPending: "Some calibration data is waiting to upload. It is saved on this device and will retry automatically when the connection is available.",
|
|
7
7
|
uploadStorageWarning: "Some calibration data could not be saved on this device yet. Keep the app open and retry uploading before closing it.",
|
|
8
8
|
phoneUploadPending: "Calibration data is waiting to upload. Keep the app open until uploading finishes so these readings are not lost.",
|
|
9
|
+
phoneUploadsAutomatic: "Calibration readings upload automatically under this session ID. Keep the app open while calibrating.",
|
|
9
10
|
retryUpload: "Retry calibration upload",
|
|
10
11
|
introduction: "Keep Marty connected to USB power. We will collect {{count}} readings each for air and white, then save the calibration. Keep the lighting the same throughout.",
|
|
11
12
|
sensor: "Colour sensor",
|
|
12
13
|
selectSensor: "Select a colour sensor",
|
|
13
14
|
selectReplacementSensor: "The sensor selected in diagnostics is no longer attached. Select the colour sensor you want to calibrate.",
|
|
14
15
|
step: "Step {{number}} of 2",
|
|
15
|
-
air: "Lift Marty about 30 cm above the surface with both feet clear. Hold it steady and capture the air readings.",
|
|
16
|
+
air: "Leave USB power connected. Lift Marty about 30 cm above the surface with both feet clear. Hold it steady and capture the air readings.",
|
|
16
17
|
white: "Place the foot with the selected colour sensor flat on a matt white surface, with the sensor fully over it. Hold Marty steady and capture the white readings.",
|
|
17
18
|
duration: "Each capture takes about 3–4 seconds once sampling starts. Preparing or restoring sensor settings can take a few extra seconds.",
|
|
18
19
|
preparing: "Preparing the sensor…",
|
|
@@ -30,8 +31,8 @@ var english = {
|
|
|
30
31
|
calibrationRequired: "Calibrate the colour sensor",
|
|
31
32
|
saved: "Calibration saved on Marty: {{count}} readings each for air and white.",
|
|
32
33
|
reconnectStep: "Final step: reconnect Marty",
|
|
33
|
-
reconnect: "Disconnect
|
|
34
|
-
disconnectToFinish: "Disconnect
|
|
34
|
+
reconnect: "Leave the USB cable plugged in. Use Disconnect in app below, then use Connect Marty to connect the same robot again. Your calibration is saved. Colour diagnostics will unlock once Marty has loaded the new sensor settings.",
|
|
35
|
+
disconnectToFinish: "Disconnect in app",
|
|
35
36
|
disconnecting: "Disconnecting Marty…",
|
|
36
37
|
loadingCalibration: "Marty has reconnected. Waiting for the new sensor settings and fresh readings…",
|
|
37
38
|
calibrationCheckDelayed: "Marty is connected, but the sensor check is taking longer than expected. The app is retrying automatically. Keep the sensor attached and Marty on USB power. If this continues, disconnect and reconnect Marty.",
|
|
@@ -46,6 +47,7 @@ var english = {
|
|
|
46
47
|
notInAir: "Lift Marty so both feet are clear of the surface, then try again.",
|
|
47
48
|
sensorDisconnected: "Connect and verify Marty, with its colour sensor attached, to continue.",
|
|
48
49
|
unsupported: "This sensor or app connection does not support the new calibration yet. Update the app and reconnect Marty. Supported colour sensor firmware: type 97 / 1.3.1 and type 98 / 1.4.0–1.4.1.",
|
|
50
|
+
sensorInitialising: "The colour sensor is still getting ready. Keep Marty connected, wait a few seconds and try this step again.",
|
|
49
51
|
readFailed: "A sensor reading could not be collected. Keep Marty connected and try this step again.",
|
|
50
52
|
unstable: "The readings varied too much. Keep Marty steady and the lighting constant, then capture this position again.",
|
|
51
53
|
saturated: "The air readings reached the sensor's limit of 255. Lift Marty clear of the surface and keep it away from direct bright light, then retry. No new calibration was saved.",
|
package/dist-types/src/screens/configuration/marty/Diagnostics/ColourSensorDiagnostics/messages.d.ts
CHANGED
|
@@ -16,6 +16,10 @@ declare const colourDiagnosticsEnglish: {
|
|
|
16
16
|
prompt: string;
|
|
17
17
|
airPrompt: string;
|
|
18
18
|
result: string;
|
|
19
|
+
confidence: string;
|
|
20
|
+
confidenceUnavailable: string;
|
|
21
|
+
confidenceAbout: string;
|
|
22
|
+
confidenceHelp: string;
|
|
19
23
|
withoutAir: string;
|
|
20
24
|
firmwareAir: string;
|
|
21
25
|
waiting: string;
|
package/dist-types/src/screens/configuration/marty/Diagnostics/ColourSensorDiagnostics/messages.js
CHANGED
|
@@ -11,6 +11,10 @@ var colourDiagnosticsEnglish = {
|
|
|
11
11
|
prompt: "Place the selected sensor on the {{colour}} card.",
|
|
12
12
|
airPrompt: "Lift Marty so both feet are at least 10 cm above any card or surface, with the sensors facing down and uncovered. Keep the lighting the same and hold still.",
|
|
13
13
|
result: "Blocks interpretation: {{result}}",
|
|
14
|
+
confidence: "Confidence {{score}}/100",
|
|
15
|
+
confidenceUnavailable: "Confidence unavailable",
|
|
16
|
+
confidenceAbout: "About confidence",
|
|
17
|
+
confidenceHelp: "Rule strength, not probability. Higher scores mean more room before a colour or air cutoff. Air needs a saved calibration to score.",
|
|
14
18
|
withoutAir: "Firmware reports air; the RGB signal matches {{result}}.",
|
|
15
19
|
firmwareAir: "Firmware Air",
|
|
16
20
|
waiting: "Select a sensor and wait for fresh readings.",
|
|
@@ -9,6 +9,13 @@ export type ColourSignalProfile = {
|
|
|
9
9
|
margin: RGB;
|
|
10
10
|
};
|
|
11
11
|
export type ColourName = "red" | "yellow" | "green" | "blue" | "purple" | "air" | "unclear";
|
|
12
|
+
export type ColourConfidenceFactors = {
|
|
13
|
+
hue?: number;
|
|
14
|
+
chroma?: number;
|
|
15
|
+
saturation?: number;
|
|
16
|
+
air?: number;
|
|
17
|
+
};
|
|
18
|
+
export declare const COLOUR_CONFIDENCE_METHOD: string;
|
|
12
19
|
/** Published channels are white-normalised by the SDK; do not clamp them for classification. */
|
|
13
20
|
export declare const classifyColour: (values: RGB & {
|
|
14
21
|
clear: number;
|
|
@@ -18,6 +25,9 @@ export declare const classifyColour: (values: RGB & {
|
|
|
18
25
|
colourWithoutAirOverride: ColourName;
|
|
19
26
|
hue: number | null;
|
|
20
27
|
chroma: number;
|
|
28
|
+
confidence: number | null;
|
|
29
|
+
confidenceMethod: string;
|
|
30
|
+
confidenceFactors: ColourConfidenceFactors;
|
|
21
31
|
saturation: number;
|
|
22
32
|
signalAboveAir: boolean;
|
|
23
33
|
signalSource: string;
|
|
@@ -1,4 +1,40 @@
|
|
|
1
|
+
var __assign = (this && this.__assign) || function () {
|
|
2
|
+
__assign = Object.assign || function(t) {
|
|
3
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
4
|
+
s = arguments[i];
|
|
5
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
6
|
+
t[p] = s[p];
|
|
7
|
+
}
|
|
8
|
+
return t;
|
|
9
|
+
};
|
|
10
|
+
return __assign.apply(this, arguments);
|
|
11
|
+
};
|
|
1
12
|
import policy from "./marty-colour-policy.json";
|
|
13
|
+
export var COLOUR_CONFIDENCE_METHOD = policy.confidence.method;
|
|
14
|
+
var channels = ["red", "green", "blue"];
|
|
15
|
+
var marginScore = function (fraction) { return Number.isFinite(fraction) ? Math.round(100 * Math.max(0, Math.min(1, fraction))) : 0; };
|
|
16
|
+
var colourConfidenceFactors = function (values, hue, chroma, saturation, match, profile) {
|
|
17
|
+
var _a = match.hue, lowerHue = _a[0], upperHue = _a[1];
|
|
18
|
+
// Red's two table entries are one continuous interval across 360°/0°.
|
|
19
|
+
// That seam is not a decision boundary, so pure red must not get a zero score.
|
|
20
|
+
var sameBand = policy.boundaries.filter(function (band) { return band.name === match.name &&
|
|
21
|
+
band.chroma[0] === match.chroma[0] && band.chroma[1] === match.chroma[1]; });
|
|
22
|
+
var start = sameBand.find(function (band) { return band.hue[0] === 0; });
|
|
23
|
+
var end = sameBand.find(function (band) { return band.hue[1] >= 360; });
|
|
24
|
+
if (start && end) {
|
|
25
|
+
lowerHue = end.hue[0] - 360;
|
|
26
|
+
upperHue = start.hue[1];
|
|
27
|
+
if (hue > 180)
|
|
28
|
+
hue -= 360;
|
|
29
|
+
}
|
|
30
|
+
// Two channels determine chroma. Use the two largest channel margins as a
|
|
31
|
+
// conservative noise scale, in the same white-normalised units as the RGB.
|
|
32
|
+
var noise = channels.map(function (channel) { var _a; return (_a = profile === null || profile === void 0 ? void 0 : profile.margin[channel]) !== null && _a !== void 0 ? _a : policy.confidence.defaultChannelMargin; })
|
|
33
|
+
.sort(function (a, b) { return b - a; });
|
|
34
|
+
return __assign({ hue: marginScore(Math.min(hue - lowerHue, upperHue - hue) / policy.confidence.fullHueMarginDegrees), chroma: marginScore(Math.min(chroma - Math.max(match.chroma[0], policy.signal.minimumChroma), match.chroma[1] - chroma) / (noise[0] + noise[1])), saturation: marginScore((saturation - policy.signal.minimumSaturation) / policy.confidence.fullSaturationMargin) }, (profile && { air: marginScore(Math.max.apply(Math, channels.map(function (channel) {
|
|
35
|
+
return (values[channel] - profile.airMax[channel] - profile.margin[channel]) / profile.margin[channel];
|
|
36
|
+
}))) }));
|
|
37
|
+
};
|
|
2
38
|
/** Published channels are white-normalised by the SDK; do not clamp them for classification. */
|
|
3
39
|
export var classifyColour = function (values, profile) {
|
|
4
40
|
var r = values.red, g = values.green, b = values.blue, clear = values.clear, air = values.air;
|
|
@@ -20,7 +56,24 @@ export var classifyColour = function (values, profile) {
|
|
|
20
56
|
var colourWithoutAirOverride = confident && match ? match.name : "unclear";
|
|
21
57
|
var classifiedColour = colourWithoutAirOverride !== "unclear" ? colourWithoutAirOverride :
|
|
22
58
|
valid && air ? "air" : "unclear";
|
|
23
|
-
|
|
59
|
+
// A rule-strength score, not a statistical probability or a new acceptance
|
|
60
|
+
// gate. The weakest decision margin wins; existing colour decisions stay intact.
|
|
61
|
+
var confidence = 0;
|
|
62
|
+
var confidenceFactors = {};
|
|
63
|
+
if (colourWithoutAirOverride !== "unclear" && match) {
|
|
64
|
+
confidenceFactors = colourConfidenceFactors(values, hue, chroma, saturation, match, profile);
|
|
65
|
+
confidence = Math.min.apply(Math, Object.values(confidenceFactors));
|
|
66
|
+
}
|
|
67
|
+
else if (classifiedColour === "air") {
|
|
68
|
+
// Firmware Air alone has no measurable confidence. With calibration, all
|
|
69
|
+
// channels must agree with the air ceiling; contrary RGB evidence scores 0.
|
|
70
|
+
confidence = profile ? marginScore(Math.min.apply(Math, channels.map(function (channel) {
|
|
71
|
+
return (profile.airMax[channel] + profile.margin[channel] - values[channel]) / profile.margin[channel];
|
|
72
|
+
}))) : null;
|
|
73
|
+
if (confidence !== null)
|
|
74
|
+
confidenceFactors = { air: confidence };
|
|
75
|
+
}
|
|
76
|
+
return { classifiedColour: classifiedColour, colourWithoutAirOverride: colourWithoutAirOverride, hue: Number.isFinite(hue) ? hue : null, chroma: chroma, confidence: confidence, confidenceMethod: COLOUR_CONFIDENCE_METHOD, confidenceFactors: confidenceFactors, saturation: saturation, signalAboveAir: exceedsAir, signalSource: profile ? "calibratedAir" : "defaultRules", classificationReason: !valid ? "invalid" :
|
|
24
77
|
!exceedsAir ? "withinCalibratedAir" : confident && match ? air ? "rgbOverridesFirmwareAir" : "rgbColour" :
|
|
25
78
|
air ? "firmwareAir" : "weakOrUnknownColour" };
|
|
26
79
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import colourPolicy from "./marty-colour-policy.json";
|
|
2
|
-
import { ColourSignalProfile } from "./colour-classifier";
|
|
2
|
+
import { ColourConfidenceFactors, ColourSignalProfile } from "./colour-classifier";
|
|
3
3
|
import { ColourSensorProfile } from "./colour-sensor-profile";
|
|
4
4
|
import type { RaftObserver } from "../application/RAFTs/RaftObserver";
|
|
5
5
|
import type { RestMessageOptions } from "../types/communication-between-apps/wrapper-communication";
|
|
@@ -68,6 +68,9 @@ export type ColourReading = {
|
|
|
68
68
|
hue: number | null;
|
|
69
69
|
chroma: number;
|
|
70
70
|
classifiedColour: string;
|
|
71
|
+
confidence?: number | null;
|
|
72
|
+
confidenceMethod?: string;
|
|
73
|
+
confidenceFactors?: ColourConfidenceFactors;
|
|
71
74
|
colourWithoutAirOverride?: string;
|
|
72
75
|
saturation?: number;
|
|
73
76
|
signalAboveAir?: boolean;
|
|
@@ -93,6 +96,7 @@ export type ColourSnapshot = {
|
|
|
93
96
|
signal?: typeof colourPolicy.signal;
|
|
94
97
|
profile?: ColourSensorProfile;
|
|
95
98
|
clearBoundsUsedForClassification?: boolean;
|
|
99
|
+
confidence?: typeof colourPolicy.confidence;
|
|
96
100
|
};
|
|
97
101
|
device: {
|
|
98
102
|
id: string;
|
|
@@ -148,6 +152,9 @@ export declare const interpretColour: (vals: Record<string, number | boolean>, p
|
|
|
148
152
|
colourWithoutAirOverride: import("./colour-classifier").ColourName;
|
|
149
153
|
hue: number | null;
|
|
150
154
|
chroma: number;
|
|
155
|
+
confidence: number | null;
|
|
156
|
+
confidenceMethod: string;
|
|
157
|
+
confidenceFactors: ColourConfidenceFactors;
|
|
151
158
|
saturation: number;
|
|
152
159
|
signalAboveAir: boolean;
|
|
153
160
|
signalSource: string;
|
|
@@ -263,7 +263,8 @@ var captureUnlocked = function (sensor, expectedColour, session, signal) { retur
|
|
|
263
263
|
if (samples.length < 2)
|
|
264
264
|
throw new ColourDiagnosticError("staleReading");
|
|
265
265
|
return [2 /*return*/, __assign(__assign({ schemaVersion: 2, sessionId: session.sessionId, sessionStartedAtMs: session.startedAtMs, captureId: createId(), expectedColour: expectedColour, startedAtMs: startedAtMs, finishedAtMs: Date.now(), appVersion: packageInfo.version, classifier: { source: colourPolicy.source, airFlagTakesPrecedence: false, boundaries: BLOCKS_COLOUR_BOUNDARIES,
|
|
266
|
-
signal: colourPolicy.signal, profile: getActiveColourSensorProfile(sensor), clearBoundsUsedForClassification: false
|
|
266
|
+
signal: colourPolicy.signal, profile: getActiveColourSensorProfile(sensor), clearBoundsUsedForClassification: false,
|
|
267
|
+
confidence: colourPolicy.confidence }, device: {
|
|
267
268
|
id: sensor.raftId, type: sensor.raft.type, name: ((_c = (_b = sensor.raft).getFriendlyName) === null || _c === void 0 ? void 0 : _c.call(_b)) || sensor.raftId,
|
|
268
269
|
firmwareVersion: ((_d = sensor.raft.systemInfo) === null || _d === void 0 ? void 0 : _d.SystemVersion) || null, connectionMethod: sensor.raft.connectionMethod || null,
|
|
269
270
|
}, sensor: { id: sensor.addon.id, name: sensor.addon.name, whoAmI: sensor.addon.whoAmI } }, (((_f = (_e = sensor.raft.raftStateInfo) === null || _e === void 0 ? void 0 : _e.power) === null || _f === void 0 ? void 0 : _f.powerStatus) && { powerStatus: {
|
|
@@ -250,9 +250,12 @@ export var readColourSensorReadiness = function (sensor, signal, checkActive) {
|
|
|
250
250
|
var result = response;
|
|
251
251
|
if ((result === null || result === void 0 ? void 0 : result.rslt) === "ok" && result.colourDiagnosticsProtocol === 1 && typeof result.ready === "boolean")
|
|
252
252
|
ok(result.ready);
|
|
253
|
-
|
|
253
|
+
// An older bridge forwards this local query to firmware and replies without the diagnostics protocol.
|
|
254
|
+
else if (((result === null || result === void 0 ? void 0 : result.rslt) === "ok" || (result === null || result === void 0 ? void 0 : result.rslt) === "fail") && result.colourDiagnosticsProtocol !== 1)
|
|
254
255
|
unavailable("unsupported");
|
|
255
|
-
|
|
256
|
+
else
|
|
257
|
+
unavailable((result === null || result === void 0 ? void 0 : result.rslt) === "fail" ? "commandFailed" : "invalidResponse");
|
|
258
|
+
}, function () { return unavailable("commandFailed"); });
|
|
256
259
|
});
|
|
257
260
|
};
|
|
258
261
|
export var collectColourSensorSetup = function (sensor, signal, checkActive) { return __awaiter(void 0, void 0, void 0, function () {
|
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
"source": "Marty web app RGB signal policy v4",
|
|
3
3
|
"clearBoundsUsedForClassification": false,
|
|
4
4
|
"signal": { "minimumChroma": 8, "minimumSaturation": 0.15, "airNoiseMarginRaw": 3 },
|
|
5
|
+
"confidence": { "method": "rule-margin-v1", "fullHueMarginDegrees": 15, "fullSaturationMargin": 0.15, "defaultChannelMargin": 3 },
|
|
5
6
|
"boundaries": [
|
|
6
7
|
{ "hue": [0, 15], "chroma": [50, 200], "clear": [40, 150], "name": "red" },
|
|
7
8
|
{ "hue": [20, 65], "chroma": [40, 300], "clear": [100, 255], "name": "yellow" },
|
|
8
|
-
{ "hue": [75,
|
|
9
|
+
{ "hue": [75, 170], "chroma": [5, 100], "clear": [25, 150], "name": "green" },
|
|
9
10
|
{ "hue": [180, 240], "chroma": [40, 260], "clear": [55, 255], "name": "blue" },
|
|
10
11
|
{ "hue": [240, 320], "chroma": [5, 100], "clear": [10, 150], "name": "purple" },
|
|
11
12
|
{ "hue": [345, 361], "chroma": [50, 200], "clear": [40, 150], "name": "red" }
|