@tigerpython/robotics-libraries 1.4.0

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.
Files changed (66) hide show
  1. package/CHANGELOG +68 -0
  2. package/LICENSE +373 -0
  3. package/README.md +81 -0
  4. package/calliope/README.md +15 -0
  5. package/calliope/callibot.py +176 -0
  6. package/calliope/callibotmot.py +46 -0
  7. package/calliope/callimk.py +143 -0
  8. package/calliope/cbalarm.py +14 -0
  9. package/calliope/cpglow.py +76 -0
  10. package/calliope/cpmike.py +16 -0
  11. package/calliope/cprover.py +33 -0
  12. package/calliope/cputils.py +23 -0
  13. package/calliope/libraries.json +10 -0
  14. package/calliope/libraries.raw.json +10 -0
  15. package/calliope/min/callibot.py +97 -0
  16. package/calliope/min/callibotmot.py +23 -0
  17. package/calliope/min/callimk.py +47 -0
  18. package/calliope/min/cbalarm.py +6 -0
  19. package/calliope/min/cpglow.py +29 -0
  20. package/calliope/min/cpmike.py +8 -0
  21. package/calliope/min/cprover.py +9 -0
  22. package/calliope/min/cputils.py +7 -0
  23. package/dist/index.d.mts +124 -0
  24. package/dist/index.d.ts +124 -0
  25. package/dist/index.js +2896 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/index.mjs +2862 -0
  28. package/dist/index.mjs.map +1 -0
  29. package/microbit/README.md +48 -0
  30. package/microbit/controller.py +212 -0
  31. package/microbit/huskylens.py +479 -0
  32. package/microbit/libraries.json +19 -0
  33. package/microbit/libraries.raw.json +19 -0
  34. package/microbit/mbalarm.py +15 -0
  35. package/microbit/mbbitbot.py +127 -0
  36. package/microbit/mbglow.py +77 -0
  37. package/microbit/mbled.py +56 -0
  38. package/microbit/mbmarsrover.py +216 -0
  39. package/microbit/mbminibit.py +139 -0
  40. package/microbit/mbrobot.py +401 -0
  41. package/microbit/mbrobot_legacy.py +90 -0
  42. package/microbit/mbrobot_plus.py +179 -0
  43. package/microbit/mbrobot_plusV2.py +490 -0
  44. package/microbit/mbrobot_plusV3.py +427 -0
  45. package/microbit/mbrobotmot.py +49 -0
  46. package/microbit/mbthetabot.py +167 -0
  47. package/microbit/mbwait.py +50 -0
  48. package/microbit/mbxgo.py +173 -0
  49. package/microbit/min/controller.py +42 -0
  50. package/microbit/min/huskylens.py +145 -0
  51. package/microbit/min/mbalarm.py +6 -0
  52. package/microbit/min/mbbitbot.py +40 -0
  53. package/microbit/min/mbglow.py +29 -0
  54. package/microbit/min/mbled.py +18 -0
  55. package/microbit/min/mbmarsrover.py +62 -0
  56. package/microbit/min/mbminibit.py +50 -0
  57. package/microbit/min/mbrobot.py +82 -0
  58. package/microbit/min/mbrobot_legacy.py +45 -0
  59. package/microbit/min/mbrobot_plus.py +75 -0
  60. package/microbit/min/mbrobot_plusV2.py +102 -0
  61. package/microbit/min/mbrobot_plusV3.py +194 -0
  62. package/microbit/min/mbrobotmot.py +25 -0
  63. package/microbit/min/mbthetabot.py +47 -0
  64. package/microbit/min/mbwait.py +23 -0
  65. package/microbit/min/mbxgo.py +37 -0
  66. package/package.json +54 -0
@@ -0,0 +1,45 @@
1
+ import gc
2
+ from microbit import i2c,pin1,pin2,pin8,pin12,pin13,pin14,sleep
3
+ import machine
4
+ _g1=.097
5
+ def w(d1,d2,s1,s2):
6
+ try:i2c.write(16,bytearray([0,d1,s1]));i2c.write(16,bytearray([2,d2,s2]))
7
+ except:
8
+ print('Please switch on mbRobot!')
9
+ while True:0
10
+ def setSpeed(speed):
11
+ A=speed;global _g2
12
+ if A<20:_g2=A+5
13
+ else:_g2=A
14
+ def forward():w(0,0,_g2,_g2)
15
+ def backward():w(1,1,_g2,_g2)
16
+ def stop():w(0,0,0,0)
17
+ def right():w(0 if _g2>0 else 1,1 if _g2>0 else 0,int(_g2*.9),int(_g2*.9))
18
+ def left():w(1 if _g2>0 else 0,0 if _g2>0 else 1,int(_g2*.9),int(_g2*.9))
19
+ def rightArc(r):
20
+ A=abs(_g2)
21
+ if r<_g1:B=0
22
+ else:C=(r-_g1)/(r+_g1)*(1-A*A/200000);B=int(C*A)
23
+ if _g2>0:w(0,0,A,B)
24
+ else:w(1,1,B,A)
25
+ def leftArc(r):
26
+ A=abs(_g2)
27
+ if r<_g1:B=0
28
+ else:C=(r-_g1)/(r+_g1)*(1-A*A/200000);B=int(C*A)
29
+ if _g2>0:w(0,0,B,A)
30
+ else:w(1,1,A,B)
31
+ exit=stop
32
+ delay=sleep
33
+ def getDistance():pin1.write_digital(1);pin1.write_digital(0);B=machine.time_pulse_us(pin2,1,50000);A=int(B/58.2+.5);return A if A>0 else 255
34
+ def setLED(on):pin8.write_digital(on);pin12.write_digital(on)
35
+ def setServo(S,Angle):
36
+ if S=='S1':A=20
37
+ if S=='S2':A=21
38
+ B=A,Angle;i2c.write(16,bytes(B))
39
+ pin2.set_pull(pin2.NO_PULL)
40
+ _g2=50
41
+ irLeft=pin13
42
+ irRight=pin14
43
+ ledLeft=pin8
44
+ ledRight=pin12
45
+ forward()
@@ -0,0 +1,75 @@
1
+ _A='Please switch on mbRobot!'
2
+ from microbit import i2c,pin0,pin1,pin2,sleep
3
+ import machine,gc,music
4
+ _g1=50
5
+ _g2=.082
6
+ def w(d1,d2,s1,s2):
7
+ try:i2c.write(16,bytearray([0,d1,d2,s1,s2]))
8
+ except:print(_A)
9
+ def setSpeed(speed):
10
+ A=speed;global _g1
11
+ if A<30 and A!=0:setPID(1);_g1=A+30
12
+ elif A>=30 and A<32:setPID(0);_g1=A+2
13
+ else:setPID(0);_g1=A
14
+ def setPID(pd):i2c.write(16,bytearray([10,pd]))
15
+ def stop():setPID(0);w(0,0,0,0)
16
+ def resetSpeed():setPID(0);A=50
17
+ def forward():w(1,_g1,1,_g1)
18
+ def backward():w(2,_g1,2,_g1)
19
+ def left():A=1.825-.0175*_g1;w(2,int(_g1*A),1,int(_g1*A))
20
+ def right():A=1.825-.0175*_g1;w(1,int(_g1*A),2,int(_g1*A))
21
+ def rightArc(r):
22
+ A=abs(_g1)
23
+ if r<_g2:B=0
24
+ else:C=(r-_g2)/(r+_g2)*(1-A*A/200000);B=int(C*A)
25
+ if _g1>0:w(1,A,1,B)
26
+ else:w(2,B,2,A)
27
+ def leftArc(r):
28
+ A=abs(_g1)
29
+ if r<_g2:B=0
30
+ else:C=(r-_g2)/(r+_g2)*(1-A*A/200000);B=int(C*A)
31
+ if _g1>0:w(1,B,1,A)
32
+ else:w(2,A,2,B)
33
+ def getDistance():pin1.write_digital(1);pin1.write_digital(0);B=machine.time_pulse_us(pin2,1,50000);A=int(B/58.2-.5);return A if A>0 else 255
34
+ class Motor:
35
+ def __init__(A,id):A._id=2*id
36
+ def _f2(A,d,s):
37
+ try:i2c.write(16,bytearray([A._id,d,s]))
38
+ except:
39
+ print(_A)
40
+ while True:0
41
+ def rotate(A,s):
42
+ B=abs(s)
43
+ if s>0:A._f2(1,B)
44
+ elif s<0:A._f2(2,B)
45
+ else:A._f2(0,0)
46
+ class LEDState:OFF=0;RED=1;GREEN=2;YELLOW=3;BLUE=4;PINK=5;CYAN=6;WHITE=7
47
+ def setLED(state,stateR=None):B=state;A=stateR;A=A or B;i2c.write(16,bytearray([11,B,A]))
48
+ def setLEDLeft(state):i2c.write(16,bytearray([11,state]))
49
+ def setLEDRight(state):i2c.write(16,bytearray([12,state]))
50
+ def setAlarm(on):
51
+ if on:music.play(_g3,wait=False,loop=True)
52
+ else:music.stop()
53
+ def beep():music.pitch(2000,200,wait=False)
54
+ def ir_read_values_as_byte():i2c.write(16,bytearray([29]));A=i2c.read(16,1);return~A[0]
55
+ def setServo(S,Angle):
56
+ if S=='S1':A=20
57
+ if S=='S2':A=21
58
+ B=A,Angle;i2c.write(16,bytes(B))
59
+ class IR:L3=0;L2=1;L1=2;R1=3;R2=4;R3=5;masks=[1,2,4,8,16,32]
60
+ class IRSensor:
61
+ def __init__(A,index):A.index=index
62
+ def read_digital(A):B=ir_read_values_as_byte();return(B&IR.masks[A.index])>>A.index
63
+ irLeft=IRSensor(IR.L1)
64
+ irRight=IRSensor(IR.R1)
65
+ irL1=IRSensor(IR.L1)
66
+ irR1=IRSensor(IR.R1)
67
+ irL2=IRSensor(IR.L2)
68
+ irR2=IRSensor(IR.R2)
69
+ irL3=IRSensor(IR.L3)
70
+ irR3=IRSensor(IR.R3)
71
+ pin2.set_pull(pin2.NO_PULL)
72
+ motL=Motor(0)
73
+ motR=Motor(1)
74
+ delay=sleep
75
+ _g3=['c6:1','r','c6,1','r','r','r']
@@ -0,0 +1,102 @@
1
+ from microbit import i2c,pin0,pin1,pin2,pin13,pin14,pin15,sleep
2
+ import gc,machine,music,neopixel
3
+ _g1=50
4
+ _g2=50
5
+ _g3=50
6
+ _g4=bytearray(5)
7
+ _g5=bytes(b'\x00\x0f\x10\x10\x11\x12\x12\x13\x13\x14\x15\x15\x16\x16\x17\x18\x18\x19\x19\x1a\x1b\x1b\x1c\x1c\x1d\x1e\x1e\x1f\x1f !!""#$$%%&\')*+,-./0123456789:;;<>?ACEGIKMPRUX[^aeimquz\x7f\x84\x89\x8f\x95\x9b\xa2\xa9\xb1\xb9\xc1\xca\xd3\xdd\xe8\xf3\xff')
8
+ _g6=0
9
+ _g7=0
10
+ _g8=0
11
+ _g9=25
12
+ _g10=131
13
+ _g11=bytearray(b'\x0b\x00\x00')
14
+ _g12=neopixel.NeoPixel(pin15,4)
15
+ np_rgb_pixels=_g12
16
+ _g13=['c5:1','r','c5,1','r:3']
17
+ _g14='Please connect to Maqueen robot and switch it on.'
18
+ def _f1(dirL,powerL,dirR,powerR):
19
+ global _g4;_g4[1]=dirL;_g4[2]=powerL;_g4[3]=dirR;_g4[4]=powerR
20
+ try:i2c.write(16,_g4)
21
+ except:raise RuntimeError(_g14)
22
+ def _f2(side,dir,power):
23
+ global _g4;_g4[1+side]=dir;_g4[2+side]=power
24
+ try:i2c.write(16,_g4)
25
+ except:raise RuntimeError(_g14)
26
+ def _f3(speed,offset):return min(_g5[speed]+offset,255)
27
+ def _f4(r):
28
+ B=int(r*100);A=_g1
29
+ if A<25:A=25
30
+ H=min(abs(A-70),20)/20;C=0
31
+ if B>5:
32
+ D=A*(3*_g8-A-9*B+220);E=-14*_g8+A-200+3*A-10*B-290;C=int(D/E)
33
+ if C<2:C=2 if B>15 else 1
34
+ F=_f3(int(C),0);G=_f3(int(A),0);return F,G
35
+ def calibrate(offset,differential=0,arcScaling=0):global _g7;global _g6;global _g8;_g6=max(min(int(offset),50),-14);_g7=max(min(int(differential),150),-150);_g8=max(min(arcScaling,50),-50);setSpeed(_g1)
36
+ def setSpeed(speed):
37
+ global _g1;global _g2;global _g3;_g1=int(min(max(speed,0),100));A=_f3(_g1,_g6);B=round((1-_g1/100)*abs(_g7))if _g1>0 else 0;C=round(_g1/100*abs(_g7))
38
+ if _g7>0:_g2=A-C;_g3=A+B
39
+ else:_g2=A+B;_g3=A-C
40
+ def resetSpeed():setSpeed(50)
41
+ def stop():_f1(0,0,0,0)
42
+ def forward():_f1(0,_g2,0,_g3)
43
+ def backward():_f1(1,_g2,1,_g3)
44
+ def left():_f1(1,_g2,0,_g3)
45
+ def right():_f1(0,_g2,1,_g3)
46
+ def rightArc(radius):A,B=_f4(radius);_f1(0,B,0,A)
47
+ def leftArc(radius):A,B=_f4(radius);_f1(0,A,0,B)
48
+ class Motor:
49
+ def __init__(A,side):A._side=side
50
+ def rotate(B,speed):A=speed;C=int(min(max(abs(A),0),100));D=_f3(C,_g6);E=0 if A>0 else 1;_f2(B._side,E,D)
51
+ def setServo(servo,angle):
52
+ D=angle;A=servo
53
+ if A=='P0'or A=='S1':B=pin0
54
+ elif A=='P1'or A=='S2':B=pin1
55
+ elif A=='P2':B=pin2
56
+ else:raise ValueError("Unknown Servo. Please use 'P0', 'P1' or 'P2'.")
57
+ if D<0 or D>180:raise ValueError('Invalid angle. Must be between 0 and 180')
58
+ C=(_g10-_g9)*int(D);E=(C>>8)+(C>>10)+(C>>11)+(C>>12);F=_g9+E;B.set_analog_period(20);B.write_analog(F)
59
+ def setMinAngleVal(duty):global _g9;_g9=int(duty)
60
+ def setMaxAngleVal(duty):global _g10;_g10=int(duty)
61
+ class IRSensor:
62
+ _g21=bytes(b'\x1d')
63
+ def __init__(A,index):A._index=index
64
+ def read_digital(A):
65
+ try:i2c.write(16,IRSensor._g21)
66
+ except:raise RuntimeError(_g14)
67
+ B=~i2c.read(16,1)[0];return(B&2**A._index)>>A._index
68
+ def read_analog(A):
69
+ try:i2c.write(16,IRSensor._g21)
70
+ except:raise RuntimeError(_g14)
71
+ B=i2c.read(16,11);return B[1+A._index*2]
72
+ def ir_read_values_as_byte():i2c.write(16,bytearray([29]));A=i2c.read(16,1);return~A[0]
73
+ def getDistance():pin13.write_digital(1);pin13.write_digital(0);A=machine.time_pulse_us(pin14,1,50000);B=(A>>6)+(A>>10)+(A>>11)+(A>>12)+1;return max(min(B,500),0)if B>0 else 255
74
+ def setLED(state,stateR=None):B=state;A=stateR;global _g11;A=A if A!=None else B;_g11[1]=B;_g11[2]=A;i2c.write(16,_g11)
75
+ def setLEDLeft(state):global _g11;_g11[1]=state;i2c.write(16,_g11)
76
+ def setLEDRight(state):global _g11;_g11[2]=state;i2c.write(16,_g11)
77
+ def fillRGB(red,green,blue):
78
+ for A in range(4):_g12[A]=red,green,blue
79
+ _g12.show()
80
+ setRGB=fillRGB
81
+ def clearRGB():_g12.clear()
82
+ def posRGB(position,red,green,blue):
83
+ A=position
84
+ if A<0 or A>3:raise ValueError('invalid RGB-LED position. Must be 0,1,2 or 3.')
85
+ _g12[A]=red,green,blue;_g12.show()
86
+ def setAlarm(state):
87
+ if state:music.play(_g13,wait=False,loop=True)
88
+ else:music.stop()
89
+ def beep():music.pitch(440,200,wait=False)
90
+ class LEDState:ON=1;OFF=0;RED=1
91
+ class IR:R2=0;R1=1;M=2;L1=3;L2=4;masks=[1,2,4,8,16]
92
+ pin2.set_pull(pin2.NO_PULL)
93
+ delay=sleep
94
+ irR2=IRSensor(0)
95
+ irR1=IRSensor(1)
96
+ irRight=irR1
97
+ irM=IRSensor(2)
98
+ irL1=IRSensor(3)
99
+ irLeft=irL1
100
+ irL2=IRSensor(4)
101
+ motL=Motor(0)
102
+ motR=Motor(2)
@@ -0,0 +1,194 @@
1
+ _B=True
2
+ _A=False
3
+ from microbit import i2c,sleep,running_time,pin0,pin1,pin2
4
+ import neopixel,music
5
+ _g1=bytearray(5)
6
+ _g2=50
7
+ _g3=50
8
+ _g4=50
9
+ _g5=bytes(b'\x00\x0f\x10\x10\x11\x12\x12\x13\x13\x14\x15\x15\x16\x16\x17\x18\x18\x19\x19\x1a\x1b\x1b\x1c\x1c\x1d\x1e\x1e\x1f\x1f !!""#$$%%&\')*+,-./0123456789:;;<>?ACEGIKMPRUX[^aeimquz\x7f\x84\x89\x8f\x95\x9b\xa2\xa9\xb1\xb9\xc1\xca\xd3\xdd\xe8\xf3\xff')
10
+ _g6=0
11
+ _g7='Please connect to Maqueen robot and switch it on.'
12
+ _g8=neopixel.NeoPixel(pin1,4)
13
+ _g9=['c5:1','r','c5,1','r:3']
14
+ _g10=bytearray(1)
15
+ _g11=bytearray(2)
16
+ _g12=16
17
+ _g13=25
18
+ _g14=131
19
+ _g15=8
20
+ def _f1(reg):_g10[0]=reg;i2c.write(_g12,_g10)
21
+ def _f2(reg,val):_g11[0]=reg;_g11[1]=val;i2c.write(_g12,_g11)
22
+ def _f3(dirL,powerL,dirR,powerR):
23
+ global _g1;_g1[1]=dirL;_g1[2]=powerL;_g1[3]=dirR;_g1[4]=powerR
24
+ try:i2c.write(16,_g1)
25
+ except:raise RuntimeError(_g7)
26
+ def _f4(side,dir,power):
27
+ global _g1;_g1[1+side]=dir;_g1[2+side]=power
28
+ try:i2c.write(16,_g1)
29
+ except:raise RuntimeError(_g7)
30
+ def setSpeed(speed):A=speed;global _g2;global _g3;global _g4;_g2=int(min(max(A,0),100));_g3=int(round(2.4*A+14));_g4=int(round(2.4*A+14))
31
+ def resetSpeed():setSpeed(50)
32
+ def stop():_f3(0,0,0,0)
33
+ def forward():_f3(0,_g3,0,_g4)
34
+ def backward():_f3(1,_g3,1,_g4)
35
+ def left():_f3(1,_g3,0,_g4)
36
+ def right():_f3(0,_g3,1,_g4)
37
+ def _f5(speed,offset):return min(_g5[speed]+offset,255)
38
+ def _f6(r):
39
+ B=int(r*100);A=_g2
40
+ if A<25:A=25
41
+ C=0
42
+ if B>5:
43
+ D=A*(3*_g6-A-9*B+220);E=-14*_g6+A-200+3*A-10*B-290;C=int(D/E)
44
+ if C<2:C=2 if B>15 else 1
45
+ F=_f5(int(C),0);G=_f5(int(A),0);return F,G
46
+ def rightArc(radius):A,B=_f6(radius);_f3(0,B,0,A)
47
+ def leftArc(radius):A,B=_f6(radius);_f3(0,A,0,B)
48
+ class Motor:
49
+ def __init__(A,side):A._side=side
50
+ def rotate(B,speed):A=speed;C=int(min(max(abs(A),0),100));D=C;E=0 if A>0 else 1;_f4(B._side,E,D)
51
+ def setServo(servo,angle):
52
+ D=angle;C=servo
53
+ if D<0 or D>180:raise ValueError('Invalid angle. Must be between 0 and 180')
54
+ if C in['P0','S1']:A=pin0
55
+ elif C in['P1','S2']:A=pin1
56
+ elif C in['P2','S3']:A=pin2
57
+ else:raise ValueError('Valid servo names: S1, S2, S3 or P0, P1, P2')
58
+ B=(_g14-_g13)*int(D);E=(B>>8)+(B>>10)+(B>>11)+(B>>12);F=_g13+E;A.set_analog_period(20);A.write_analog(F)
59
+ class IRSensor:
60
+ _g19=bytes(b'\x1d')
61
+ def __init__(A,index):A.index=index
62
+ def read_digital(A):
63
+ try:i2c.write(16,IRSensor._g19)
64
+ except:raise RuntimeError(_g7)
65
+ B=~i2c.read(16,1)[0];return(B&2**A.index)>>A.index
66
+ def read_analog(A):
67
+ try:_f1(29)
68
+ except:raise RuntimeError(_g7)
69
+ B=i2c.read(16,11);return B[2+2*A.index]<<8|B[1+2*A.index]
70
+ def setLEDs(rgbl,rgbr):_f2(11,rgbl);_f2(12,rgbr)
71
+ def setLED(state,stateR=None):B=state;A=stateR;A=A if A!=None else B;setLEDs(B,A)
72
+ def setLEDLeft(rgbl):_f2(11,rgbl)
73
+ def setLEDRight(rgbr):_f2(12,rgbr)
74
+ def fillRGB(red,green,blue):_g8.clear();_g8.fill((red,green,blue));_g8.show()
75
+ def setRGB(r,g,b):fillRGB(r,g,b)
76
+ def clearRGB():_g8.clear()
77
+ def posRGB(position,red,green,blue):
78
+ A=position
79
+ if A<0 or A>3:raise ValueError('invalid RGB-LED position. Must be 0,1,2 or 3.')
80
+ _g8[A]=red,green,blue;_g8.show()
81
+ def setAlarm(state):
82
+ if state:music.play(_g9,wait=_A,loop=_B)
83
+ else:music.stop()
84
+ def beep():music.pitch(440,200,wait=_A)
85
+ def readLightIntensity(side):
86
+ _f1(78);A=i2c.read(16,4,repeat=_A)
87
+ if side==1:return A[0]<<8|A[1]
88
+ else:return A[2]<<8|A[3]
89
+ def setPatrolSpeed(speed):_f2(63,speed)
90
+ def setIntersectionRunMode(mode):_f2(69,mode)
91
+ def setTRordRunMode(mode):_f2(70,mode)
92
+ def setLeftOrStraightRunMode(mode):_f2(71,mode)
93
+ def setRightOrStraightRunMode(mode):_f2(72,mode)
94
+ def patrolling(patrol):
95
+ if patrol==1:A=5
96
+ else:A=8
97
+ _f2(60,A)
98
+ def intersectionDetecting():_f1(61);A=i2c.read(16,1)[0];return A
99
+ def pidControlDistance(dir,distance,interruption):
100
+ A=distance;C=2
101
+ if A>=6000:A=60000
102
+ _f2(64,dir);_f2(85,C);_f2(65,A>>8);_f2(66,A);_f2(60,6)
103
+ if interruption==1:
104
+ _f1(87);B=i2c.read(16,1)
105
+ while B[0]==1:sleep(10);B=i2c.read(16,1)
106
+ def pidControlAngle(angle,interruption):
107
+ A=angle;D=2
108
+ if A>=0:B=1
109
+ else:B=2;A=-A
110
+ _f2(67,B);_f2(86,D);_f2(68,A);_f2(60,6)
111
+ if interruption==1:
112
+ _f1(87);C=i2c.read(16,1)
113
+ while C[0]==1:sleep(10);C=i2c.read(16,1)
114
+ def pidControlStop():_f2(60,16)
115
+ def readRealTimeSpeed(type):
116
+ _f2(76,1);A=i2c.read(16,2)
117
+ if type==1:return A[0]/5
118
+ else:return A[1]/5
119
+ def _f7(cmd,args=[]):
120
+ B=len(args);C=B+1;A=bytearray(4+B);A[0]=85;A[1]=C>>8&255;A[2]=C&255;A[3]=cmd
121
+ for(D,E)in enumerate(args):A[4+D]=E
122
+ i2c.write(51,A)
123
+ def _f8(expectedCommand):
124
+ F=1000;J=32;G=running_time();B=_A;A=None;C=_A
125
+ while running_time()-G<F and C==_A:
126
+ H=i2c.read(51,1)[0]
127
+ if H==83:C=_B
128
+ elif H==99:return B,A
129
+ sleep(16)
130
+ if C==_B:
131
+ D=i2c.read(51,3);K=D[0];L=D[1]|D[2]<<8
132
+ if K==expectedCommand:
133
+ B=_B;A=bytearray();E=L;M=min(E,J)
134
+ while running_time()-G<F and E>0:
135
+ try:I=i2c.read(51,M);A.extend(I);E-=len(I)
136
+ except:sleep(1)
137
+ return B,A
138
+ def setLidarMode(mode=8):
139
+ A=mode;global _g15
140
+ if A not in[4,8]:raise ValueError('Lidar mode must be 4 or 8')
141
+ C='4x4'if A==4 else'8x8';print('Switching Lidar Mode to '+C+'.\nPlease wait up to 10 seconds.');B=_A
142
+ for D in range(10):
143
+ _f7(1,[0,0,0,A]);B,E=_f8(1)
144
+ if B==_B:break
145
+ sleep(17)
146
+ if B:_g15=A;sleep(5000)
147
+ else:raise RuntimeError('Failed to switch Lidar Mode')
148
+ def getDistanceAt(x_pos,y_pos):
149
+ _f7(3,[x_pos,y_pos]);B,A=_f8(3)
150
+ if B and len(A)>=2:C=(A[0]|A[1]<<8)//10;return C
151
+ else:return 1023
152
+ def getDistanceList():
153
+ _f7(2);D,A=_f8(2)
154
+ if D and len(A)>=32:
155
+ B=[]
156
+ for C in range(0,len(A),2):E=A[C]|A[C+1]<<8;B.append(E//10)
157
+ return B
158
+ else:return[]
159
+ def getDistance():global _g15;A=int(_g15/2);B=getDistanceAt(A-1,A-1);C=getDistanceAt(A,A-1);D=getDistanceAt(A-1,A);E=getDistanceAt(A,A);F=[B,C,D,E];return min(F)
160
+ def getDistanceGrid():
161
+ _f7(2);G,A=_f8(2)
162
+ if G and len(A)>=32:
163
+ B=[];C=16 if len(A)==128 else 8
164
+ for D in range(0,len(A),C):
165
+ E=[]
166
+ for F in range(0,C,2):H=A[D+F]|A[D+F+1]<<8;E.append(H//10)
167
+ B.append(E)
168
+ return B
169
+ else:return[]
170
+ def getDistanceColumn(index):
171
+ _f7(5,[index]);D,A=_f8(5)
172
+ if D and len(A)>=8:
173
+ B=[]
174
+ for C in range(0,len(A),2):E=A[C]|A[C+1]<<8;B.append(E//10)
175
+ return B
176
+ return[]
177
+ def getDistanceRow(index):
178
+ _f7(6,[index]);D,A=_f8(6)
179
+ if D and len(A)>=8:
180
+ B=[]
181
+ for C in range(0,len(A),2):E=A[C]|A[C+1]<<8;B.append(E//10)
182
+ return B
183
+ return[]
184
+ pin2.set_pull(pin2.NO_PULL)
185
+ delay=sleep
186
+ irR2=IRSensor(0)
187
+ irR1=IRSensor(1)
188
+ irRight=irR1
189
+ irM=IRSensor(2)
190
+ irL1=IRSensor(3)
191
+ irLeft=irL1
192
+ irL2=IRSensor(4)
193
+ motL=Motor(0)
194
+ motR=Motor(2)
@@ -0,0 +1,25 @@
1
+ import gc
2
+ from microbit import i2c,pin1,pin2,pin8,pin12,pin13,pin14,sleep
3
+ import machine
4
+ class Motor:
5
+ def __init__(A,id):A._id=2*id
6
+ def rotate(A,s):
7
+ B=abs(s)
8
+ if s>0:A._f2(0,B)
9
+ elif s<0:A._f2(1,B)
10
+ else:A._f2(0,0)
11
+ def _f2(A,d,s):
12
+ try:i2c.write(16,bytearray([A._id,d,s]))
13
+ except:
14
+ print('Please switch on mbRobot!')
15
+ while True:0
16
+ delay=sleep
17
+ def getDistance():pin1.write_digital(1);pin1.write_digital(0);B=machine.time_pulse_us(pin2,1,50000);A=int(B/58.2+.5);return A if A>0 else 255
18
+ def setLED(on):pin8.write_digital(on);pin12.write_digital(on)
19
+ pin2.set_pull(pin2.NO_PULL)
20
+ irLeft=pin13
21
+ irRight=pin14
22
+ ledLeft=pin8
23
+ ledRight=pin12
24
+ motL=Motor(0)
25
+ motR=Motor(1)
@@ -0,0 +1,47 @@
1
+ from microbit import*
2
+ from utime import ticks_us,sleep_us
3
+ from neopixel import*
4
+ _g1=50
5
+ _g2=40
6
+ _g3=40
7
+ _g4=bytes(b'\x00\x0b\x0b\x0c\x0c\r\r\r\x0e\x0e\x0f\x0f\x0f\x10\x10\x11\x11\x11\x12\x12\x13\x13\x13\x14\x14\x15\x15\x15\x16\x16\x17\x17\x17\x18\x19\x1a\x1b\x1b\x1c\x1d\x1e\x1f !"##$%&\'()*++,-./0123468:<?ADFILOSVZ^bgkpu{\x81\x87\x8d\x94\x9b\xa3\xab\xb4\xbd\xc6\xd0\xdb\xe6\xf2\xff')
8
+ _g5=0
9
+ _g6=0
10
+ _g7=0
11
+ _g8=34
12
+ _g9=14
13
+ def _f1(dirL,powerL,dirR,powerR):pinsL=pin14,pin13;pinsR=pin16,pin15;pinsL[dirL].write_analog(powerL);pinsL[1-dirL].write_analog(0);pinsR[dirR].write_analog(powerR);pinsR[1-dirR].write_analog(0)
14
+ def _f2(side,direction,power):
15
+ if side==0:pins=pin14,pin13
16
+ elif side==2:pins=pin16,pin15
17
+ pins[direction].write_analog(power);pins[1-direction].write_analog(0)
18
+ def _f3(r):
19
+ outerSpeed=_g1;rCm=int(r*100);threshold=outerSpeed-max(rCm+20,40)
20
+ if threshold<=0:outerSpeed=min(max(rCm+40,40),100)
21
+ reducedSpeed=0
22
+ if rCm>=4:flattening=(100-outerSpeed)//2;reducedSpeed=(rCm*10-35)/(rCm*(11+(_g7-4)/10)+90+flattening);reducedSpeed=reducedSpeed*outerSpeed
23
+ innerByte=_f4(int(reducedSpeed),0);outerByte=_f4(int(outerSpeed),0);return innerByte,outerByte
24
+ def calibrate(offset,differential=0,arcScaling=0):global _g6;global _g5;global _g7;_g5=max(min(int(offset),150),-10);_g6=max(min(int(differential),150),-150);_g7=max(min(arcScaling,50),-15);setSpeed(_g1)
25
+ def setSpeed(speed):
26
+ global _g1;global _g2;global _g3;_g1=int(min(max(speed,0),100));powerByte=_f4(_g1,_g5);boost=round((1-_g1/100)*abs(_g6))if _g1>0 else 0;reduction=round(_g1/100*abs(_g6))
27
+ if _g6>0:_g2=powerByte-reduction;_g3=powerByte+boost
28
+ else:_g2=powerByte+boost;_g3=powerByte-reduction
29
+ def _f4(speed,offset):speedIndex=int(speed*(len(_g4)-1)/100);return min(_g4[speedIndex]+offset,1023)
30
+ def stop():_f1(0,0,0,0)
31
+ def forward():_f1(0,_g2,0,_g3)
32
+ def backward():_f1(1,_g2,1,_g3)
33
+ def left():_f1(1,_g2,0,_g3)
34
+ def right():_f1(0,_g2,1,_g3)
35
+ def rightArc(radius):inner,outer=_f3(radius);_f1(0,outer,0,inner)
36
+ def leftArc(radius):inner,outer=_f3(radius);_f1(0,inner,0,outer)
37
+ def getDistance():
38
+ pin12.write_digital(1);sleep_us(10);pin12.write_digital(0);pin12.set_pull(pin15.NO_PULL)
39
+ while pin12.read_digital()==0:0
40
+ start=ticks_us()
41
+ while pin12.read_digital()==1:0
42
+ end=ticks_us();echo=end-start;distance=int(.01715*echo);return distance
43
+ def setLED(position,red,green,blue):global _g8;i2c_data=bytearray(5);i2c_data[0]=1;i2c_data[1]=position;i2c_data[2]=red;i2c_data[3]=green;i2c_data[4]=blue;i2c.write(_g8,i2c_data)
44
+ def fill(red,green,blue):
45
+ for position in range(_g9):setLED(position,red,green,blue)
46
+ def readLine(side):i2c.write(_g8,bytearray([side+1]),False);result=i2c.read(_g8,2);result=result[0]+(result[1]<<8);return result
47
+ def readLight(side):i2c.write(_g8,bytearray([side+3]),False);result=i2c.read(_g8,2);result=result[0]+(result[1]<<8);return result
@@ -0,0 +1,23 @@
1
+ from microbit import button_a,button_b,pin0,pin1,pin2,pin_logo,sleep
2
+ POLLING_DELAY=100
3
+ def wait_for_press(button='any'):
4
+ A=button;button_a.was_pressed();button_b.was_pressed()
5
+ if A=='a'or A=='A':
6
+ while not button_a.was_pressed():sleep(POLLING_DELAY)
7
+ elif A=='b'or A=='B':
8
+ while not button_b.was_pressed():sleep(POLLING_DELAY)
9
+ elif A=='any'or A=='ANY':
10
+ while not button_a.was_pressed()and not button_b.was_pressed():sleep(POLLING_DELAY)
11
+ elif A=='both'or A=='ab'or A=='AB':
12
+ while not(button_a.is_pressed()and button_b.is_pressed()):sleep(POLLING_DELAY)
13
+ while button_a.is_pressed()or button_b.is_pressed():sleep(POLLING_DELAY)
14
+ else:raise RuntimeError("Button to wait for must be either: 'a', 'b', 'any' or 'both'.")
15
+ def wait_for_touch(pin='logo'):
16
+ B=pin;A=pin_logo
17
+ if B=='pin0':A=pin0
18
+ elif B=='pin1':A=pin1
19
+ elif B=='pin2':A=pin2
20
+ elif B=='logo'or B=='pin_logo'or B=='pinLogo':A=pin_logo
21
+ else:raise RuntimeError("Argument 'pin' must be one of: 'pin_logo', 'pin0', 'pin1' or 'pin2'.")
22
+ A.set_touch_mode(A.CAPACITIVE)
23
+ while not A.is_touched():sleep(POLLING_DELAY)
@@ -0,0 +1,37 @@
1
+ from microbit import*
2
+ _g1=50
3
+ _g2=False
4
+ _g3=pin14
5
+ _g4=pin13
6
+ def checkInit(func):
7
+ def wrapper(*args,**kwargs):
8
+ global _g2
9
+ if not _g2:init_xgo_serial(_g3,_g4)
10
+ return func(*args,**kwargs)
11
+ return wrapper
12
+ def _f1(speed,in_min,in_max,out_min,out_max):return(speed-in_min)*(out_max-out_min)//(in_max-in_min)+out_min
13
+ @checkInit
14
+ def _f2(direction,speed):
15
+ move_buffer=bytearray(9);move_buffer[0]=85;move_buffer[1]=0;move_buffer[2]=9;move_buffer[3]=0;move_buffer[7]=0;move_buffer[8]=170;speed=max(0,min(100,speed))
16
+ if direction==0:move_buffer[4]=48;move_buffer[5]=_f1(speed,0,100,128,255)
17
+ elif direction==1:move_buffer[4]=48;move_buffer[5]=_f1(speed,0,100,128,0)
18
+ elif direction==2:move_buffer[4]=49;move_buffer[5]=_f1(speed,0,100,128,0)
19
+ elif direction==3:move_buffer[4]=49;move_buffer[5]=_f1(speed,0,100,128,255)
20
+ move_buffer[6]=~(9+move_buffer[4]+move_buffer[5])&255;uart.write(move_buffer)
21
+ @checkInit
22
+ def clampX(milimeters=50):clampBuffer=bytearray(9);clampBuffer[0]=85;clampBuffer[1]=0;clampBuffer[2]=9;clampBuffer[3]=0;clampBuffer[4]=115;clampBuffer[7]=0;clampBuffer[8]=170;clampBuffer[5]=milimeters;clampBuffer[6]=~(124+clampBuffer[5])&255;uart.write(clampBuffer);sleep(1000)
23
+ @checkInit
24
+ def clampZ(milimeters=50):clampBuffer=bytearray(9);clampBuffer[0]=85;clampBuffer[1]=0;clampBuffer[2]=9;clampBuffer[3]=0;clampBuffer[4]=116;clampBuffer[7]=0;clampBuffer[8]=170;clampBuffer[5]=milimeters;clampBuffer[6]=~(125+clampBuffer[5])&255;uart.write(clampBuffer);sleep(1000)
25
+ @checkInit
26
+ def clamp(force):clampBuffer=bytearray(9);clampBuffer[0]=85;clampBuffer[1]=0;clampBuffer[2]=9;clampBuffer[3]=0;clampBuffer[4]=113;clampBuffer[7]=0;clampBuffer[8]=170;clampBuffer[5]=force;clampBuffer[6]=~(122+clampBuffer[5])&255;uart.write(clampBuffer);sleep(1000)
27
+ def init_xgo_serial(tx_pin,rx_pin,baudrate=115200):global _g2;uart.init(baudrate=baudrate,tx=tx_pin,rx=rx_pin);init_action();_g2=True
28
+ def init_action():commands_buffer=bytearray(9);commands_buffer[0]=85;commands_buffer[1]=0;commands_buffer[2]=9;commands_buffer[3]=0;commands_buffer[4]=62;commands_buffer[5]=255;commands_buffer[6]=185;commands_buffer[7]=0;commands_buffer[8]=170;uart.write(commands_buffer);sleep(2000)
29
+ @checkInit
30
+ def action(id):commands_buffer=bytearray(9);commands_buffer[0]=85;commands_buffer[1]=0;commands_buffer[2]=9;commands_buffer[3]=0;commands_buffer[4]=62;commands_buffer[5]=id;commands_buffer[6]=~(71+id)&255;commands_buffer[7]=0;commands_buffer[8]=170;uart.write(commands_buffer);sleep(2000)
31
+ def changeInit(tx,rx):global _g3;global _g4;_g3=tx;_g4=rx;init_xgo_serial(_g3,_g4)
32
+ @checkInit
33
+ def setSpeed(speed):global _g1;_g1=speed
34
+ def forward():_f2(0,_g1)
35
+ def backward():_f2(1,_g1)
36
+ def left():_f2(2,_g1)
37
+ def right():_f2(3,_g1)
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "@tigerpython/robotics-libraries",
3
+ "version": "1.4.0",
4
+ "description": "TigerJython robotics modules (micro:bit, Calliope mini) with minified and raw Python sources, plus a typed JS/TS API for easy integration.",
5
+ "license": "MPL-2.0",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+ssh://git@gitlab.inf.ethz.ch/public-dkomm/webtp/robotics_libraries.git"
9
+ },
10
+ "keywords": [
11
+ "tigerjython",
12
+ "tigerpython",
13
+ "robotics",
14
+ "microbit",
15
+ "calliope-mini",
16
+ "micropython"
17
+ ],
18
+ "publishConfig": {
19
+ "access": "public"
20
+ },
21
+ "main": "./dist/index.js",
22
+ "module": "./dist/index.mjs",
23
+ "types": "./dist/index.d.ts",
24
+ "exports": {
25
+ ".": {
26
+ "types": "./dist/index.d.ts",
27
+ "import": "./dist/index.mjs",
28
+ "require": "./dist/index.js"
29
+ },
30
+ "./calliope/*": "./calliope/*",
31
+ "./microbit/*": "./microbit/*",
32
+ "./package.json": "./package.json"
33
+ },
34
+ "files": [
35
+ "dist",
36
+ "calliope",
37
+ "microbit",
38
+ "README.md",
39
+ "LICENSE",
40
+ "CHANGELOG"
41
+ ],
42
+ "scripts": {
43
+ "build:py": "python3 script.py",
44
+ "build:ts": "tsup",
45
+ "build": "npm run build:py && npm run build:ts",
46
+ "prepare": "husky && npm run build",
47
+ "prepublishOnly": "npm run build"
48
+ },
49
+ "devDependencies": {
50
+ "husky": "^9.1.7",
51
+ "tsup": "^8.3.5",
52
+ "typescript": "^5.7.2"
53
+ }
54
+ }