From e4008a3a73828398b2a8ae88607d6c9c4d1f3056 Mon Sep 17 00:00:00 2001 From: Amerlander Date: Sat, 15 Feb 2020 22:16:34 +0100 Subject: [PATCH] Fixes display and fonts (#85) * change simulator svg * change radio image * Remove google fonts cdn * change color of 'advanced' button * font fix * font fix 2 * display fix * change fullsceen simulator bg * Continuous servo * handle continuous state * adding shims * update rendering for continuous servos * fixing sim * fix sig * typo * fix sim * bump pxt * bump pxt * rerun travis --- libs/core/_locales/core-jsdoc-strings.json | 1 + libs/core/pins.cpp | 8 ++++ libs/core/pinscompat.ts | 7 +++ libs/core/shims.d.ts | 6 +++ sim/state/edgeconnector.ts | 7 +++ sim/state/edgeconnectorsim.ts | 5 ++ sim/state/microservo.ts | 40 +++++++++++----- sim/visuals/microbit.ts | 56 +++++++++++----------- theme/style.less | 16 +++---- 9 files changed, 96 insertions(+), 50 deletions(-) diff --git a/libs/core/_locales/core-jsdoc-strings.json b/libs/core/_locales/core-jsdoc-strings.json index 623e7e30..a64b06e8 100644 --- a/libs/core/_locales/core-jsdoc-strings.json +++ b/libs/core/_locales/core-jsdoc-strings.json @@ -535,6 +535,7 @@ "pins.pulseIn": "Return the duration of a pulse at a pin in microseconds.", "pins.pulseIn|param|name": "the pin which measures the pulse, eg: DigitalPin.P0", "pins.pulseIn|param|value": "the value of the pulse, eg: PulseValue.High", + "pins.servoSetContinuous": "Specifies that a continuous servo is connected.", "pins.servoSetPulse": "Configure the IO pin as an analog/pwm output and set a pulse width. The period is 20 ms period and the pulse width is set based on the value given in **microseconds** or `1/1000` milliseconds.", "pins.servoSetPulse|param|micros": "pulse duration in micro seconds, eg:1500", "pins.servoSetPulse|param|name": "pin name", diff --git a/libs/core/pins.cpp b/libs/core/pins.cpp index ebf27d11..63b27295 100644 --- a/libs/core/pins.cpp +++ b/libs/core/pins.cpp @@ -258,6 +258,14 @@ namespace pins { PINOP(setServoValue(value)); } + /** + * Specifies that a continuous servo is connected. + */ + //% + void servoSetContinuous(AnalogPin name, bool value) { + // handled in simulator + } + /** * Configure the IO pin as an analog/pwm output and set a pulse width. The period is 20 ms period and the pulse width is set based on the value given in **microseconds** or `1/1000` milliseconds. * @param name pin name diff --git a/libs/core/pinscompat.ts b/libs/core/pinscompat.ts index 2a728f78..ed29ed21 100644 --- a/libs/core/pinscompat.ts +++ b/libs/core/pinscompat.ts @@ -48,6 +48,9 @@ interface PwmOnlyPin extends DigitalInOutPin, AnalogOutPin { //% parts=microservo trackArgs=0 servoSetPulse(duration: number): void; + + //% parts=microservo tracArgs=0 + servoSetContinuous(value: boolean): void; } //% noRefCounting fixedInstances @@ -109,6 +112,10 @@ class MicrobitPin implements AnalogInPin, AnalogOutPin, AnalogInOutPin, PwmOnlyP pins.servoWritePin(this.analogId(), value); } + servoSetContinuous(value: boolean): void { + pins.servoSetContinuous(this.analogId(), value); + } + servoSetPulse(duration: number): void { pins.servoSetPulse(this.analogId(), duration); } diff --git a/libs/core/shims.d.ts b/libs/core/shims.d.ts index 6f89f2d4..f86d9eb1 100644 --- a/libs/core/shims.d.ts +++ b/libs/core/shims.d.ts @@ -732,6 +732,12 @@ declare namespace pins { //% name.fieldOptions.tooltips="false" name.fieldOptions.width="250" shim=pins::servoWritePin function servoWritePin(name: AnalogPin, value: int32): void; + /** + * Specifies that a continuous servo is connected. + */ + //% shim=pins::servoSetContinuous + function servoSetContinuous(name: AnalogPin, value: boolean): void; + /** * Configure the IO pin as an analog/pwm output and set a pulse width. The period is 20 ms period and the pulse width is set based on the value given in **microseconds** or `1/1000` milliseconds. * @param name pin name diff --git a/sim/state/edgeconnector.ts b/sim/state/edgeconnector.ts index 15a250b7..e32d6c4d 100644 --- a/sim/state/edgeconnector.ts +++ b/sim/state/edgeconnector.ts @@ -81,6 +81,13 @@ namespace pxsim.pins { pin.servoAngle = value; } + export function servoSetContinuous(pinId: number, value: boolean) { + let pin = getPin(pinId); + if (!pin) return; + + pin.servoSetContinuous(value); + } + export function servoSetPulse(pinId: number, micros: number) { let pin = getPin(pinId); if (!pin) return; diff --git a/sim/state/edgeconnectorsim.ts b/sim/state/edgeconnectorsim.ts index 055309de..d4e04a45 100644 --- a/sim/state/edgeconnectorsim.ts +++ b/sim/state/edgeconnectorsim.ts @@ -17,6 +17,7 @@ namespace pxsim { mode = PinFlags.Unused; pitch = false; pull = 0; // PullDown + servoContinuous = false; digitalReadPin(): number { this.mode = PinFlags.Digital | PinFlags.Input; @@ -59,6 +60,10 @@ namespace pxsim { runtime.queueDisplayUpdate(); } + servoSetContinuous(value: boolean) { + this.servoContinuous = !!value; + } + servoSetPulse(pinId: number, micros: number) { // TODO } diff --git a/sim/state/microservo.ts b/sim/state/microservo.ts index 5eb54d58..0f9629bd 100644 --- a/sim/state/microservo.ts +++ b/sim/state/microservo.ts @@ -10,7 +10,7 @@ namespace pxsim.visuals { - + @@ -24,6 +24,7 @@ namespace pxsim.visuals { return { el: createMicroServoElement(), x: xy[0], y: xy[1], w: 112.188, h: 299.674 }; } + const SPEED = 300; // 0.1s/60 degree export class MicroServoView implements IBoardPart { public style: string = ""; public overElement: SVGElement = undefined; @@ -61,21 +62,36 @@ namespace pxsim.visuals { translateEl(this.element, [x, y]) } updateState(): void { - this.targetAngle = 180.0 - this.state.getPin(this.pin).servoAngle; - if (this.targetAngle != this.currentAngle) { + const p = this.state.getPin(this.pin); + const continuous = !!p.servoContinuous; + const servoAngle = p.servoAngle; + if (continuous) { + // for a continuous servo, the angle is interpreted as a rotation speed + // 0 -> -100%, 90 - 0%, 180 - 100% const now = U.now(); - const cx = 56.661; - const cy = 899.475; - const speed = 300; // 0.1s/60 degree const dt = Math.min(now - this.lastAngleTime, 50) / 1000; - const delta = this.targetAngle - this.currentAngle; - this.currentAngle += Math.min(Math.abs(delta), speed * dt) * (delta > 0 ? 1 : -1); - this.crankEl.setAttribute("transform", this.crankTransform - + ` rotate(${this.currentAngle}, ${cx}, ${cy})`) - this.lastAngleTime = now; - setTimeout(() => runtime.updateDisplay(), 20); + this.currentAngle = this.targetAngle; + this.targetAngle += ((servoAngle - 90) / 90) * SPEED * dt; + } else { + this.targetAngle = 180.0 - servoAngle; } + if (this.targetAngle != this.currentAngle) + this.renderAngle(); } + + private renderAngle() { + const now = U.now(); + const cx = 56.661; + const cy = 899.475; + const dt = Math.min(now - this.lastAngleTime, 50) / 1000; + const delta = this.targetAngle - this.currentAngle; + this.currentAngle += Math.min(Math.abs(delta), SPEED * dt) * (delta > 0 ? 1 : -1); + this.crankEl.setAttribute("transform", this.crankTransform + + ` rotate(${this.currentAngle}, ${cx}, ${cy})`) + this.lastAngleTime = now; + setTimeout(() => runtime.updateDisplay(), 20); + } + updateTheme(): void { } diff --git a/sim/visuals/microbit.ts b/sim/visuals/microbit.ts index 1cc064a0..c1c4bd14 100644 --- a/sim/visuals/microbit.ts +++ b/sim/visuals/microbit.ts @@ -145,7 +145,7 @@ namespace pxsim.visuals { } `; const BOARD_SVG = ` - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/style.less b/theme/style.less index b0dc2495..572782ad 100644 --- a/theme/style.less +++ b/theme/style.less @@ -14,20 +14,14 @@ *******************************/ /* Roboto font */ -// @RobotoMonoFont: data-uri("../docs/static/fonts/Roboto_Mono_400_normal.woff2"); +@RobotoMonoFont: data-uri("../docs/static/fonts/roboto-mono-v7-latin-regular.woff"); /* roboto-mono-regular - latin */ @font-face { font-family: 'Roboto Mono'; font-style: normal; font-weight: 400; - src: url('../static/fonts/roboto-mono-v7-latin-regular.eot'); /* IE9 Compat Modes */ - src: local('Roboto Mono'), local('RobotoMono-Regular'), - url('../static/fonts/roboto-mono-v7-latin-regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ - url('../static/fonts/roboto-mono-v7-latin-regular.woff2') format('woff2'), /* Super Modern Browsers */ - url('../static/fonts/roboto-mono-v7-latin-regular.woff') format('woff'), /* Modern Browsers */ - url('../static/fonts/roboto-mono-v7-latin-regular.ttf') format('truetype'), /* Safari, Android, iOS */ - url('../static/fonts/roboto-mono-v7-latin-regular.svg#RobotoMono') format('svg'); /* Legacy iOS */ + src: @RobotoMonoFont format('woff'); } .ui.button.download-button { &:extend(.ui.purple.button all); @@ -58,9 +52,12 @@ &:extend(.ui.blue.button all); } -#filelist, #editortools { +#filelist, #editortools, .fullscreensim #boardview { background: #fff data-uri("../docs/static/logo_texture.png") 0 0 repeat !important; } +.fullscreensim #mainmenu { + background: #1b1c1d !important; +} #downloadArea { background: transparent !important; @@ -97,7 +94,6 @@ @media only screen and (min-width: @largeMonitorBreakpoint) { } - /* Download dialog */ .ui.downloaddialog.modal>.content { padding: 1rem;