Skip to content

Commit 434e784

Browse files
UnheardWolf344BeepBot99
authored andcommitted
Implement Servo Hub Configuration
1 parent 0da9496 commit 434e784

File tree

6 files changed

+61
-22
lines changed

6 files changed

+61
-22
lines changed

src/App.svelte

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,27 @@
22
import Hub from "./lib/Hub.svelte";
33
import CodeDisplay from "./lib/CodeDisplay.svelte";
44
import xmlBuilder from "./lib/xmlBuilder.js";
5-
import {createEmptyLynxModule, type LynxModule} from "./lib";
5+
import {createEmptyLynxModule, createEmptyMotorLynxModule, type LynxModule, type MotorLynxModule} from "./lib";
6+
import MotorHub from "./lib/MotorHub.svelte";
67
7-
let controlHub: LynxModule = $state(createEmptyLynxModule());
8-
let expansionHub: LynxModule = $state(createEmptyLynxModule());
8+
let controlHub: MotorLynxModule = $state(createEmptyMotorLynxModule());
9+
let expansionHub: MotorLynxModule = $state(createEmptyMotorLynxModule());
10+
let servoHub: LynxModule = $state(createEmptyLynxModule());
911
1012
let configuring = $state(true);
1113
</script>
1214

1315
<div class="min-h-dvh grid lg:grid-cols-2 lg:p-6 gap-6 bg-base-100">
1416
<div class:hidden={configuring}
1517
class="max-w-screen mb-16 lg:mb-0 lg:block bg-base-200 p-4 lg:p-6 lg:rounded-md lg:shadow-sm lg:border-2 lg:border-base-content/20">
16-
<CodeDisplay codeBuilder={xmlBuilder} {controlHub} {expansionHub}/>
18+
<CodeDisplay codeBuilder={xmlBuilder} {controlHub} {expansionHub} {servoHub}/>
1719
</div>
1820
<div class:hidden={!configuring}
1921
class="lg:block bg-base-200 mb-16 lg:mb-0 lg:rounded-md lg:shadow-sm lg:border-2 lg:border-base-content/20 p-4 lg:p-6">
2022
<div class="tabs tabs-lift h-[calc(100%---spacing(10))]">
21-
<Hub name="Control Hub" bind:module={controlHub} checked={true}/>
22-
<Hub name="Expansion Hub" bind:module={expansionHub}/>
23+
<MotorHub name="Control Hub" bind:module={controlHub} checked={true}/>
24+
<MotorHub name="Expansion Hub" bind:module={expansionHub}/>
25+
<Hub name="Servo Hub" bind:module={servoHub}/>
2326
</div>
2427
</div>
2528
</div>

src/lib/CodeDisplay.svelte

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,19 @@
33
44
import hljs from "highlight.js";
55
import type {Action} from "svelte/action";
6-
import type {LynxModule} from "./index";
6+
import type {LynxModule, MotorLynxModule} from "./index";
77
import type {CodeBuilder} from "./xmlBuilder";
88
99
interface Props {
10-
controlHub: LynxModule;
11-
expansionHub: LynxModule;
10+
controlHub: MotorLynxModule;
11+
expansionHub: MotorLynxModule;
12+
servoHub: LynxModule;
1213
codeBuilder: CodeBuilder;
1314
}
1415
15-
let {controlHub, expansionHub, codeBuilder}: Props = $props();
16+
let {controlHub, expansionHub, servoHub, codeBuilder}: Props = $props();
1617
17-
let code = $derived(codeBuilder.build(controlHub, expansionHub))
18+
let code = $derived(codeBuilder.build(controlHub, expansionHub, servoHub))
1819
1920
onMount(() => {
2021
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {

src/lib/Hub.svelte

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<script lang="ts">
2-
import {type Device, DeviceTypes, type LynxModule} from "./index";
2+
import {type Device, DeviceTypes, type LynxModule, type MotorLynxModule} from "./index";
33
import DeviceGroup from "./DeviceGroup.svelte";
44
55
interface Props {
@@ -13,9 +13,5 @@
1313

1414
<input type="radio" name="hub" class="tab" aria-label={name} {checked}/>
1515
<div class="tab-content bg-base-100 border-base-300 p-6">
16-
<DeviceGroup type="Motors" bind:devices={module.motors} deviceTypes={DeviceTypes.MOTORS}/>
1716
<DeviceGroup type="Servos" bind:devices={module.servos} deviceTypes={DeviceTypes.SERVOS}/>
18-
<DeviceGroup type="I<sup>2</sup>C Devices" bind:devices={module.i2c} deviceTypes={DeviceTypes.I2C}/>
19-
<DeviceGroup type="Digital Devices" bind:devices={module.digital} deviceTypes={DeviceTypes.DIGITAL}/>
20-
<DeviceGroup type="Analog Devices" bind:devices={module.analog} deviceTypes={DeviceTypes.ANALOG}/>
2117
</div>

src/lib/MotorHub.svelte

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<script lang="ts">
2+
import {type Device, DeviceTypes, type LynxModule, type MotorLynxModule} from "./index";
3+
import DeviceGroup from "./DeviceGroup.svelte";
4+
5+
interface Props {
6+
name: string;
7+
checked?: boolean;
8+
module: MotorLynxModule;
9+
}
10+
11+
let {name, checked = false, module = $bindable()}: Props = $props();
12+
</script>
13+
14+
<input type="radio" name="hub" class="tab" aria-label={name} {checked}/>
15+
<div class="tab-content bg-base-100 border-base-300 p-6">
16+
<DeviceGroup type="Motors" bind:devices={module.motors} deviceTypes={DeviceTypes.MOTORS}/>
17+
<DeviceGroup type="Servos" bind:devices={module.servos} deviceTypes={DeviceTypes.SERVOS}/>
18+
<DeviceGroup type="I<sup>2</sup>C Devices" bind:devices={module.i2c} deviceTypes={DeviceTypes.I2C}/>
19+
<DeviceGroup type="Digital Devices" bind:devices={module.digital} deviceTypes={DeviceTypes.DIGITAL}/>
20+
<DeviceGroup type="Analog Devices" bind:devices={module.analog} deviceTypes={DeviceTypes.ANALOG}/>
21+
</div>

src/lib/index.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,23 @@ export interface DeviceType {
1010
}
1111

1212
export interface LynxModule {
13-
motors: Device[];
1413
servos: Device[];
14+
}
15+
16+
export interface MotorLynxModule extends LynxModule {
17+
motors: Device[];
1518
i2c: Device[];
1619
digital: Device[];
1720
analog: Device[];
1821
}
1922

2023
export function createEmptyLynxModule(): LynxModule {
24+
return {
25+
servos: [],
26+
}
27+
}
28+
29+
export function createEmptyMotorLynxModule(): MotorLynxModule {
2130
return {
2231
motors: [],
2332
servos: [],

src/lib/xmlBuilder.ts

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,33 @@
1-
import type {LynxModule} from "./index";
1+
import type {LynxModule, MotorLynxModule} from "./index";
22
import {create} from "xmlbuilder2";
33
import type {XMLBuilder} from "xmlbuilder2/lib/interfaces";
44

55
export interface CodeBuilder {
6-
build(controlHub: LynxModule, expansionHub: LynxModule): string;
6+
build(controlHub: MotorLynxModule, expansionHub: MotorLynxModule, servoHub: LynxModule): string;
77
}
88

99
class XmlBuilder implements CodeBuilder {
10-
build(controlHub: LynxModule, expansionHub: LynxModule): string {
10+
build(controlHub: MotorLynxModule, expansionHub: MotorLynxModule, servoHub: LynxModule): string {
1111
const doc = create({version: '1.0', standalone: true, encoding: "UTF-8"})
1212
.ele("Robot", {type: "FirstInspires-FTC"})
1313
.ele("LynxUsbDevice", {name: "Control Hub Portal", serialNumber: "(embedded)", parentModuleAddress: 173})
1414
const controlHubBuilder = doc.ele("LynxModule", {name: "Control Hub", port: 173});
15-
XmlBuilder.buildLynxModule(controlHubBuilder, controlHub);
15+
XmlBuilder.buildMotorLynxModule(controlHubBuilder, controlHub);
1616
const expansionHubBuilder = doc.ele("LynxModule", {name: "Expansion Hub 0", port: 0});
17-
XmlBuilder.buildLynxModule(expansionHubBuilder, expansionHub);
17+
XmlBuilder.buildMotorLynxModule(expansionHubBuilder, expansionHub);
18+
const servoHubBuilder = doc.ele("LynxModule", {name: "Servo Hub 1", port: 1});
19+
XmlBuilder.buildLynxModule(servoHubBuilder, servoHub);
20+
1821
return doc.end({prettyPrint: true});
1922
}
2023

2124
private static buildLynxModule(doc: XMLBuilder, module: LynxModule) {
25+
for (const servo of module.servos) {
26+
doc.ele(servo.type.type, {name: servo.name, port: servo.port});
27+
}
28+
}
29+
30+
private static buildMotorLynxModule(doc: XMLBuilder, module: MotorLynxModule) {
2231
for (const motor of module.motors) {
2332
doc.ele(motor.type.type, {name: motor.name, port: motor.port});
2433
}

0 commit comments

Comments
 (0)