-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathroversa.ts
More file actions
316 lines (290 loc) · 10 KB
/
Copy pathroversa.ts
File metadata and controls
316 lines (290 loc) · 10 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
/**
* The pins used by Roversa
*/
//%
enum RoversaPin {
//% block="Menu"
P5 = DAL.MICROBIT_ID_IO_P8,
//% block="Play"
P8 = DAL.MICROBIT_ID_IO_P5,
//% block="Stop"
P9 = DAL.MICROBIT_ID_IO_P9,
//% block="Forward"
P13 = DAL.MICROBIT_ID_IO_P13,
//% block="Reverse"
P14 = DAL.MICROBIT_ID_IO_P14,
//% block="Right Turn"
P15 = DAL.MICROBIT_ID_IO_P15,
//% block="Left Turn"
P16 = DAL.MICROBIT_ID_IO_P16,
}
/**
* The event raised by the Roversa pins
*/
//%
enum RoversaEvent {
//% block="click"
Click = DAL.MICROBIT_BUTTON_EVT_CLICK,
//% block="down"
Down = DAL.MICROBIT_BUTTON_EVT_DOWN,
//% block="up"
Up = DAL.MICROBIT_BUTTON_EVT_UP,
}
/**
* Blocks for driving the Roversa robot
*/
//% weight=100 color=#d55e00 icon="\uf085" block="Roversa"
//% groups="['Buttons', 'Basic', 'Advanced', 'Calibrate']"
namespace roversa {
/**
* **********************************************************************************************************************************************
* micro:bit roversa
************************************************************************************************************************************************/
/* Some parameters used for controlling the turn and length of the roversa robot */
const milliSecInASecond = 1000
let distancePerSec = 100
let numberOfDegreesPerSec = 200
let biasToApply = 50 //in the middle is the place to start
/**
*
*/
let initialized = false;
function init() {
if (initialized) return;
pins.pushButton(DigitalPin.P5)
pins.pushButton(DigitalPin.P8)
pins.pushButton(DigitalPin.P9)
pins.pushButton(DigitalPin.P13)
pins.pushButton(DigitalPin.P14)
pins.pushButton(DigitalPin.P15)
pins.pushButton(DigitalPin.P16)
initialized = true;
}
function forwardHard(): void {
let P1Output = 180;
let P2Output = 0;
if (biasToApply < 50) {
// Want to move 180 towards 90
P2Output -= 50 - biasToApply;
} else if (biasToApply > 50) {
// Want to move 0 towards 90
P1Output += biasToApply - 50;
}
pins.servoWritePin(AnalogPin.P1, P1Output);
pins.servoWritePin(AnalogPin.P2, P2Output);
}
function backwardHard(): void {
let P1Output = 0;
let P2Output = 180;
if (biasToApply < 50) {
// Want to move 0 towards 90
P2Output += 50 - biasToApply;
} else if (biasToApply > 50) {
// Want to move 180 towards 90
P1Output -= biasToApply - 50;
}
pins.servoWritePin(AnalogPin.P1, P1Output);
pins.servoWritePin(AnalogPin.P2, P2Output);
}
/**
* Determines if a button is pressed
* @param button the pin that acts as a button
*/
//% blockId=roversa_ispressed block="Roversa button %button|is pressed"
//% group="Buttons" weight=91
//% button.fieldEditor="gridpicker" button.fieldOptions.columns=3
export function isPressed(button: RoversaPin): boolean {
const pin = <DigitalPin><number>button;
pins.setPull(pin, PinPullMode.PullUp);
return pins.digitalReadPin(<DigitalPin><number>button) == 0;
}
/**
* Registers code to run when a Roversa button is detected.
*/
//% blockId=roversa_onevent block="Roversa button on %button|%event"
//% group="Buttons" weight=90
//% button.fieldEditor="gridpicker" button.fieldOptions.columns=3
//% event.fieldEditor="gridpicker" event.fieldOptions.columns=3
export function onEvent(button: RoversaPin, event: RoversaEvent, handler: Action) {
init();
control.onEvent(<number>button, <number>event, handler); // register handler
}
/**
* Drives backwards. Call stop to stop
*/
//% blockId=roversa_servos_backward
//% group="Basic" weight=86
//% block="drive backward"
export function backward(): void {
let P1Output = 0;
let P2Output = 180;
if (biasToApply < 50) {
// Want to move 180 towards 90
P2Output -= 50 - biasToApply;
} else if (biasToApply > 50) {
// Want to move 0 towards 90
P1Output += biasToApply - 50;
}
pins.servoWritePin(AnalogPin.P1, P1Output);
pins.servoWritePin(AnalogPin.P2, P2Output);
basic.pause(1250);
stop();
}
/**
* Drives forward. Call stop to stop
*/
//% blockId=roversa_servos_forward
//% group="Basic" weight=87
//% block="drive forward"
export function forward(): void {
let P1Output = 180;
let P2Output = 0;
if (biasToApply < 50) {
// Want to move 0 towards 90
P2Output += 50 - biasToApply;
} else if (biasToApply > 50) {
// Want to move 180 towards 90
P1Output -= biasToApply - 50;
}
pins.servoWritePin(AnalogPin.P1, P1Output);
pins.servoWritePin(AnalogPin.P2, P2Output);
basic.pause(1250);
stop();
}
/**
* Turns left. Call stop to stop
*/
//% blockId=roversa_servos_left
//% group="Basic" weight=85
//% block="turn left"
export function left(): void {
pins.servoWritePin(AnalogPin.P1, 0);
pins.servoWritePin(AnalogPin.P2, 0);
basic.pause(650);
stop();
}
/**
* Turns right. Call stop to stop
*/
//% blockId=roversa_servos_right
//% group="Basic" weight=84
//% block="turn right"
export function right(): void {
pins.servoWritePin(AnalogPin.P1, 180);
pins.servoWritePin(AnalogPin.P2, 180);
basic.pause(650);
stop();
}
/**
* Drives forwards the requested distance and then stops
* @param howFar distance to move
*/
//% blockId=roversa_drive_forwards
//% group="Advanced" weight=81
//% block="drive forwards %howFar|distance"
export function driveForwards(howFar: number): void {
let timeToWait = (howFar * milliSecInASecond) / distancePerSec; // calculation done this way round to avoid zero rounding
forwardHard();
basic.pause(timeToWait);
stop();
}
/**
* Drives backwards the requested distance and then stops
* @param howFar distance to move
*/
//% blockId=roversa_drive_backwards
//% group="Advanced" weight=80
//% block="drive backwards %howFar|distance"
export function driveBackwards(howFar: number): void {
let timeToWait = (howFar * milliSecInASecond) / distancePerSec; // calculation done this way round to avoid zero rounding
backwardHard();
basic.pause(timeToWait);
stop();
}
/**
* Turns right through the requested degrees and then stops
* needs NumberOfDegreesPerSec tuned to make accurate, as it uses
* a simple turn, wait, stop method.
* Runs the servos at slower than the right function to reduce wheel slip
* @param deg how far to turn, eg: 90
*/
//% blockId=roversa_turn_right
//% group="Advanced" weight=79
//% block="turn right %deg|degrees"
export function turnRight(deg: number): void {
let timeToWait = (deg * milliSecInASecond) / numberOfDegreesPerSec;// calculation done this way round to avoid zero rounding
pins.servoWritePin(AnalogPin.P1, 130);
pins.servoWritePin(AnalogPin.P2, 130);
basic.pause(timeToWait);
stop();
}
/**
* Turns left through the requested degrees and then stops
* needs NumberOfDegreesPerSec tuned to make accurate, as it uses
* a simple turn, wait, stop method.
* Runs the servos at slower than the right function to reduce wheel slip
* @param deg how far to turn, eg: 90
*/
//% blockId=roversa_turn_left
//% group="Advanced" weight=78
//% block="turn left %deg|degrees"
export function turnLeft(deg: number): void {
let timeToWait = (deg * milliSecInASecond) / numberOfDegreesPerSec;// calculation done this way round to avoid zero rounding
pins.servoWritePin(AnalogPin.P1, 50);
pins.servoWritePin(AnalogPin.P2, 50);
basic.pause(timeToWait);
stop()
}
/**
* Stop for 360 servos.
* rather than write 90, which may not stop the servo moving if it is out of trim
* this stops sending servo pulses, which has the same effect.
* On a normal servo this will stop the servo where it is, rather than return it to neutral position.
* It will also not provide any holding force.
*/
//% blockId=roversa_servos_stop
//% group="Advanced" weight=77
//% block="stop"
export function stop(): void {
pins.analogWritePin(AnalogPin.P1, 0);
pins.analogWritePin(AnalogPin.P2, 0);
}
/**
* Apply a bias to the wheels. 0 to 50 for left, 50 to 100 for right.
* @param bias eg: 50
*/
//% blockId=roversa_servos_bias
//% group="Calibrate" weight=69
//% block="bias %biasDriving"
//% bias.min=0 bias.max=100
export function biasDriving(bias:number): void {
if (bias > 100) {
bias = 100;
} else if (bias < 0) {
bias = 0;
}
biasToApply = bias;
}
/**
* Allows the setting of roversa turn amount.
* This allows tuning for the turn x degrees commands
* @param degPerSec : How many degrees per second the robot does.
*/
//% blockId=roversa_set_turn_speed_param
//% group="Calibrate" weight=68
//% block="calibrate turn amount to %degPerSec|degrees per second"
export function setDegreesPerSecond(degPerSec: number): void {
numberOfDegreesPerSec = degPerSec
}
/**
* Allows the setting of roversa forward / reverse distance.
* This allows tuning for the move x distance commands
* @param distPerSec : How many mm per second the robot does.
*/
//% blockId=roversa_set_movement_speed_param
//% group="Calibrate" weight=67
//% block="calibrate drive amount to %distPerSec|mm per second"
export function setDistancePerSecond(distPerSec: number): void {
distancePerSec = distPerSec
}
}