G15 PMN Open Robotics=======================================================Groundwork also for the {upcoming} Avenuege Robot==============================================================================================================When you know what's here, try OpenRobotics SUBPAGES:genifun.com/openrobotics/subpage_first_bookscan=======================================================Those who love the human mind & body,and who at most like machines,can be excellent programmers.And they can program robots.But they are beyond talking about "AI".==============================================================================================================Welcome to algorithms for robots,written in the most human mind friendlyprogramming language, G15 PMN, and,importantly, written in a first-hand way.=======================================================Shall we start, then? If you are curiousabout avoiding to attribute psychological words,such as "mind", "intelligence", "awareness","thought", "feeling", "creativity", "intention""learning" and "intuition" to human artefacts,feel free to explore texts, packages and links at
the G15 PMN app page.The rest of this page is hard programming, for ahuman-friendly form of robotics in which there isno attempt to make machines mimick life, butrather to serve life, in a humble way, withinstable and very narrow contexts, and ethically so.=======================================================First, we need to have a good way of sending andreceiving suitable bundles of signals between theG15 PC and the various parts of the robot.Let's give this signal a somewhat luxurious space,more so than the 32 bit number. How about 60 bit?This becomes something like a number, up to 17digits (optionally signed), in which we can encodesome program signals incl real 32-bit numbers.These numbers we consistently use when setting upwhat we call the "FCM matrix", at the input andoutput side of it. The miniprogram 'somecalc6'helps us to think about encoding into 60b nums.However, we don't set up FCM in general--but wedo it once we have one or more robot tasksdefined. The core program lets us to begin toentrain the motor movements of the robot. As wethen apply the matching over its cameras and such,we set up the FCM--this is done in subpages of thispage, one robotic app expanding on the core, for eachrobotic hardware applied to a certain set of tasks.{definition of 60-bit numbers starts at card i:72}

=======================================================The CORE G15 PMN Robotics app is here: 5558889.zip.This was completed January 30th, 2018. In case there isanything to correct in it, an extra date is given here,alongside the correction, but note: the G15 PMN roboappsusing this core have comments ABOUT this core, after it,so as to clear up possible confusions and also to correcttiny issues or misleading commentaries in it; we aim tokeep the core unchanged except if it is really important.This is being put to use in the concrete tasks, wherethe core is suitably adapted {see links just ahead}.Start up the app in G15CONTROL {installationinstructions are written at bottom of this page,do check out the 'ethics footnote', #6, as well}{or, for testing of suitable algorithms without robotattached, in any G15 PMN environment} and, inside theThird Foundation G15 PMN terminal, you interactivelysteer the robot and fetch input from it and viewvariables and function states and make new functions.For instance, type somecalc6to check out the effect of the 60-bit definition.Type vurobocam1 to check out camera#1on the robot (see footnotes as to all roboconfigurations).To start up the camera this way, each time, snatch a photo,and exit the camera program, steered via G15 PMN, ensuresgood cleansing of PC Ram; however the USB cameras usuallyinvolves a good pause when accessed this way. Indeed, incase of doing vurobocam1 as a loop, a pause should be putin after it, eg a number and then activepause.In addition, such USB-camera background setups may notgive consistent result every time, and so the integrityof the fetched image should be checked by the programbefore it decides things after matching over it. But for roboprogramming, it makes sense not to rely onvery often updates from its sensory apparatus. Rather,the program should rapidly analyze whatever it has got,allowing time whenever anything is sent to OR fetched from,the robohardware. Then, as you orient the robot to aprofessional task, you can check out such as continualphotographing as background process in case of increasedspeed requirements in the final form of the robosetup.Type rrr to move the roboservosto a good rest position. With very light servos, you canhand-position it towards a rest position. Run eg the pairof rrr and robotswing some times initially, until robotmoves smoothly. Do rrr always at least once, and, if indoubt, before any use of recact.Be prepared to switch robot electronics off and back on,adjust its position physically, and run rrr and such,{all this repeated several times when it's necessary}when the robot is in extra need of resetting its workings.This may for instance happen during intense entrainmentof new moves, but also when the roboservos has encounteredtoo much resistance and they signal to the electronicsthat the position array is probably out of tune. To learnto reset a robot, and find ways of doing so elegantly, isan art. But the more powerful servos and motors and suchthe robot has, the more physical distance it must have toyou and other people and sensitive objects when suchresetting is necessary. Read about health precautions infootnotes to this page. And really do take care, it simplyisn't worth it, to risk health just to get a machine adjusted.This is the one big thing that distinguishes roboticprogramming from programming. Just think ahead, withconstant top priority to health, and you'll do it fine.Type robotswing to check outa complementary set of roboservo positions compared to rest.Type recact to start recordinga movement sequence where PgUp and PgDn changes theposition, and 0, 1, 2, 3, 4 selects channel, Esc quits.The robot moves as you click the keyboard. Be sure totype in recactinfo and learn about it byexperimentation; since recact clears the recentrecording from RAM each time you save it, you shouldaccess its Save command to save useful robomovesbefore exiting it; you should consider its estimateas to how many disk cards it requires to save a robomovesequence approximate and always set aside some extracards; the recact autoexits in case the recactarraygets full--but you can adjust the size of this inthe config cards; you must position the robot inidentical state before doing pract, to avoid jerkymovements; and finally you can learn to append torobomove sequences stored on disk if you load them,perform them with pract, go back into recactand reload from disk, then via keyboard move therobot more, and store the expanded robomove to disk.Type pract to put the robotthrough the most recently recorded or loaded robomove,{Be sure that if you did rrr just before recact, youdo something like rrr again, just before pract,so that the first movement fits where it first begun.}The sequence can then be stored somewhere else, eg disk,and used by the program together with pattern matching.{The location in RAM is an array called recactarray.}And, of course, type qu to quit the terminal,followed by CTR-Q and the word REB and lineshift toexit G15 PMN and do a power off of the robot.Before the program core is listed, we link again to thesubpages of this page, where this core is expandedwith a FCM solution for each task set that eachrobohardware is shaped to do. As explained ina footnote, FCM must be shaped according to task andcontext rather than done once and for all.=======================================================Links to subpages of this page, where the core programhas been expanded on with suitable G15 PMN FCM matricesof data and algorithms inside the program, and witha suitable entrained database as well, for simple ormedium-advanced or advanced robotic activity:genifun.com/openrobotics/subpage_first_bookscan==============================================================================================================This, then, is the G15 PMN Open Robotics core program,and it is deliberately kept concise and simple--becausethat is, indeed, part of the idea of openness.Above it you find links to the subpages, whereeverything from the tiniest to huge concreterobotic tasks for concrete robotic hardware arecarried out, expanding on a suitably altered formof just this core.=======================================================
<i1>
|core g15 |a suitable
|open robotics |extra pd's;To
|app#5558889 |be run in an
|by srweber |environment
|alias atwlah; |like g15robot
|Builds on |This uses fcm
|3rdfoundation |to steer all
|g15 pmn with |about robots
<i2>
|^^^^^^^^^^^^^ |^^^^^^^^^^^^^
|Next, we |to/from robot
|have config |are set up; &
|cards, where |config for
|the commands |what the robo
|to put and |app does, in
|get signals |general
|() |() ()
<i3>
|^^^^^^^^^^^^^ |^^^^^^^^^^^^^
|Note that the |changed to
|g15 pmn |fit various
|functions |hardware, and
|to interact |these funcs
|w/roboparts |are gathered
|are easily |together
|() |() ()
<i4>
|^^^^^^^^^^^^^ |^^^^^^^^^^^^^
|So when you |SPECIFIC
|change the |ROBOFUNCTIONS
|config cards, |{approx 300
|go to card |cards ahead}
|section named |and make
|HARDWARE |updates there
|() |() ()
<i5>
|^^^^^^^^^^^^^ |^^^^^^^^^^^^^
|Note that |initial rest
|some robots |position
|need a rather |accurately
|intensive |fit the info
|initprocedure |in channel
|to make its |electronics
|() |() ()
<i6>
|^^^^^^^^^^^^^ |^^^^^^^^^^^^^
|Also note |you must use
|that, because |creative
|of Goedel, |perception of
|there is no |context&robot
|canonical fcm |to program it
|setup:rather |suitably
|() |() ()
<i7>
rg1tx= |A config card
&incam.bmp&.
|File made by
|command rg1
|and fetched
|by this app
|as caminput,
|robopart#1
<i8>
rg2tx= |A config card
&in2cam.bmp&.
|File made by
|command rg2
|and fetched
|by this app
|as caminput,
|robopart#1
<i9>
rg3tx= |A config card
&in3cam.bmp&.
|File made by
|command rg3
|and fetched
|by this app
|as caminput,
|robopart#1
<i10>
cmdrg1= |a config card
^. cmdrg1
longtxt* kl
./incam.sh
*txtcomplete |gets input
|from part#1
|of robot:
cliptrail |camera #1
<i11>
cmdrg2= |a config card
^. cmdrg2
longtxt* kl
./in2cam.sh
*txtcomplete |gets input
|from part#1
|of robot:
cliptrail |camera #2
<i12>
cmdrg3= |a config card
^. cmdrg3
longtxt* kl
./in3cam.sh
*txtcomplete |gets input
|from part#1
|of robot:
cliptrail |camera #3
<i13>
pr1tx= |A config card
&pr1.txt&.
|File made by
|this app &
|used by
|cmdpr1 to
|send signals
|to robopart#1
<i14>
cmdpr1= |a config card
^. cmdpr1
longtxt* kl
cat pr1.txt >
/dev/ttyUSB0 |sends the
*txtcomplete |signalpackage
|to part#1 of
cliptrail |the robot
<i15>
crlnmarker= |a config card
&~&.
crlnnumber=
13. |when the "~"
|As configured |char is used,
|here: in "put |it becomes
|robot" {pr} |ascii line-
|calls, |shift
<i16>
pr1aresttx=
^. *txtcomplete
longtxt* |config card
#0 p1500 #4 p7 cliptrail
50 t1800~ pr1aresttx
kl
|robopart#1a:
|rest position
<i17>
pr1bresttx=
^. *txtcomplete
longtxt* |config card
#1 p1700 t1800 cliptrail
~ pr1bresttx
kl
|robopart#1b:
|rest position
<i18>
pr1cresttx=
^. *txtcomplete
longtxt* |config card
#3 p1750 #2 p1 cliptrail
700 t2000~ pr1cresttx
kl
|robopart#1c:
|rest position
<i19>
pr1aswingtx=
^. *txtcomplete
longtxt* |config card
#0 p750 #4 p22 cliptrail
20 t1800~ pr1aswingtx
kl
|robopart#1a:
|a swing pos
<i20>
pr1bswingtx=
^. *txtcomplete
longtxt* |config card
#1 p1850 t1800 cliptrail
~ pr1bswingtx
kl
|robopart#1b:
|a swing pos
<i21>
pr1cswingtx=
^. *txtcomplete
longtxt* |config card
#3 p1950 #2 p1 cliptrail
950 t2000~ pr1cswingtx
kl
|robopart#1c:
|a swing pos
<i22>
pr1stdmovtim= |This is used
1900. |as ms timer
|parameter
|when robopart
|#1 moved by
|some of the
|std config
|commands
<i23>
actarraylen= |a config card
33333.
|Must be roomy
|The command |robomovs via
|"recact" |keyboard;this
|allows you to |number sets
|record a |maxlen of
|sequence of |recorded act
<i24>
maxqtychan= |a config card
333.
|Can be roomy;
|number used
|to make array
|with a number
|for each
|robochannel
<i25>
pauseaftervu= |a config card
65.
|When the g15 |a slight wait
|calls command |eg 65ms will
|line of a |ensure proper
|kind that |screen update
|pauses g15, |when looping
|eg get video, |such comcalls
<i26>
|a config card
<i27>
|a config card
<i28>
|a config card
<i29>
|a config card
<i30>
|a config card
<i31>
|a config card
<i32>
|a config card
<i33>
|a config card
<i34>
|a config card
<i35>
|a config card
<i36>
|a config card
<i37>
|a config card
<i38>
|a config card
<i39>
commandline= 1
|in: quote 2
|action:what 3
|quote says 4
s5 x4
lc |For a g15 pmn
i5 |environment
tt |like g15robot
<i40>
sh |This command
sh |uses "x4"
sh |which can
sh. |(despite
|apply care; |comments in
|also, max len |pd code) work
|quote MUST be |in all suit-
|within 230 |able contexts
<i41>
pr1= |BE SURE:max
|in:quote |len is 230!
|action: |use syntax
|sends quote |matching robo
|to robot via |electronics;
|file pr1tx |the quote
|{as set in |must already
|config cards} |be "crparsed"
<i42>
tx |qty incl nil:
pr1tx
|from: lk
pr1tx up
up
|to:
lc fw
<i43>
|from: |qty
jx jx
up lk
fw
|makes file:
jx
|to: lk
sc br
<i44>
|The command cmdpr1
|has been lk
|stored; file
|name next
|used in
|transmitting
|to robopart
|#1 commandline.
<i45>
miniarray= &&
^. miniarray
222 kl
232
mm
|Gem image |some cards
|array |from the g15
sz |gem program
<i46>
maxiarray= &&
^. maxiarray
500 kl
503
mm 500
|Expanded gem 500
|image matrix maxiarray
sz wwyymatrix
<i47>
clrexpimage= clrexpimage
250000
maxiarray
lk
clrthismany.
<i48>
loadanyarray= t4
|In: disknum, t3
|cardnum, qty, t2
|array t1
|Action: puts | and room
|qty cards to | enough is:
|array, which | 232 times
|must've room | qty cards
<i49>
ll:99999999 j3
dc
j3 t3
0
eq
se
ex
<i50>
j1 lc
j2 j4
rr 232
fw
<i51>
j4 j2
232 up
ad t2
t4 lo.
<i52>
loadpackimage= t3
|In: disknum, t2
|cardnum, t1
|array j1
|Action: gets j2
|gem image to 216
|one long j3
|enough array loadanyarray.
<i53>
unpackimage= s6
|In: inarray, s5
|matrix
|Action: i5
|Unpacks tones 50000
|0->255 to a i6
|matrix sized kp.
|500x500
<i54>
rg1= |tmp use:ldisk
|Gives:1=found |Config info
|Action: |used:cmdrg1
|Photographs |and rg1tx;
|from robopart |this command
|#1, camera#1, |assumedly
|via c9000 to |may take
|maxiarray; |seconds
<i55>
|The command cmdrg1
|as has been lk
|configured
|in the first
|cards calls
|on camera#1
|of the
|robot commandline
<i56>
|from: |qty incl nil:
rg1tx rg1tx
up lk
|gem image up
|is put to
|c9000 fw
|to: |Fetch gem pd:
lc rq
<i57>
d2 3
9000
|Unchanged miniarray
|array when lk
|image not
|found:
basis
ex loadpackimage
<i58>
miniarray
lk
maxiarray
lk
unpackimage dance.
<i59>
rg2= |tmp use:ldisk
|Gives:1=found |Config info
|Action: |used:cmdrg2
|Photographs |and rg2tx;
|from robopart |this command
|#1, camera#2, |assumedly
|via c9000 to |may take
|maxiarray; |seconds
<i60>
|The command cmdrg2
|as has been lk
|configured
|in the first
|cards calls
|on camera#2
|of the
|robot commandline
<i61>
|from: |qty incl nil:
rg2tx rg2tx
up lk
|gem image up
|is put to
|c9000 fw
|to: |Fetch gem pd:
lc rq
<i62>
d2 3
9000
|Unchanged miniarray
|array when lk
|image not
|found:
basis
ex loadpackimage
<i63>
miniarray
lk
maxiarray
lk
unpackimage dance.
<i64>
rg3= |tmp use:ldisk
|Gives:1=found |Config info
|Action: |used:cmdrg2
|Photographs |and rg3tx;
|from robopart |this command
|#1, camera#3, |assumedly
|via c9000 to |may take
|maxiarray; |seconds
<i65>
|The command cmdrg3
|as has been lk
|configured
|in the first
|cards calls
|on camera#3
|of the
|robot commandline
<i66>
|from: |qty incl nil:
rg3tx rg3tx
up lk
|gem image up
|is put to
|c9000 fw
|to: |Fetch gem pd:
lc rq
<i67>
d2 3
9000
|Unchanged miniarray
|array when lk
|image not
|found:
basis
ex loadpackimage
<i68>
miniarray
lk
maxiarray
lk
unpackimage dance.
<i69>
vurobocam1= rg1
|action: sh
|Calls on the maxiarray
|robocam 1, lk
|puts to maxi- sw
|array, shows
|at upper left pauseaftervu
|corner activepause.
<i70>
vurobocam2= rg2
|action: sh
|Calls on the maxiarray
|robocam 2, lk
|puts to maxi- sw
|array, shows
|at upper left pauseaftervu
|corner activepause.
<i71>
vurobocam3= rg3
|action: sh
|Calls on the maxiarray
|robocam 3, lk
|puts to maxi- sw
|array, shows
|at upper left pauseaftervu
|corner activepause.
<i72>
|^^^^^^^^^^^^^ |^^^^^^^^^^^^^
|Next, we |digit series
|define 60bit |to encode &
|numbers, also |receive info
|called num60b |to and from
|or just num6, |the robotic
|as suitable |parts
|() |() ()
<i73>
extractsign= |c is 1 or !1
|in: a |as its sign;
|gives: b c |this allows
|action: a is |easy saving
|number, can |of sign,
|be signed; |which can
|b is its |later be 'mm'
|absolute; |back in :)
<i74>
f d2
ab
|note: basis dance
|is considered ex
|unsigned
w
0
lt !1.
<i75>
twoto= se
|in: number |note:
|gives: 2^ n ex
s3 |uses loop
1 2
ll:2000000000 mm
i3 q3
n? lo.
<i76>
array2up= |So, for
1^. |instance,
|For FAST 2^n |to get 2 with
45 |the exponent
sz |5, write:
&& | 5
&array2up& | array2up
setfastvar | ay
<i77>
initarray2up= undefnum
ll:31 31
m1 array2up
twoto ya.
m1 initarray2up
array2up |Signed32bit
ya |means careful
lo |with 2^31
<i78>
get2pow= |range as we
|in: number |define it (ie
|gives: exp |avoid the
|action: |"undefnum"),
|Given a |it gives n so
|number from |that 2^n is
|1 up to the |it, or less
|maximum 32bit |than 2^{n up}
<i79>
s4 d3
ll:31
m1 m1
array2up dc
ay ex
i4
lo
le 30.
<i80>
twoto23= |signbit, exp
8388608. |8 bits, then
first23bits= |a 23bit
8388607. |"mantissa",
|32b socalled |which, with
|"floating |a resolution,
|point nums" |is added to
|{fpnums} have |2 ^ exp
<i81>
first16bits= &high16bits&
65535. setfastvar
first31bits=
high16bits= 2147483647.
1. first30bits=
1073741823.
first16bits first15bits=
ng 32767.
<i82>
first8bits= first16bits
255. an
^top8bitsof16
top8bitsof16= setfastvar
1. twoto30=
1073741824.
first8bits twoto15=
ng 32768.
<i83>
ngfirst8bits= ng
1.
|This has 1's
|for 32 bit
|except first
|group of bits ^ngfirst8bits
first8bits setfastvar
<i84>
ngsecond8bits= ng
1.
|This has 1's
|for 32 bit
|except second
|group of bits ^ngsecond8bits
top8bitsof16 setfastvar
<i85>
signedbytemax= signedintmax=
127. 32767.
signedbytemin= signedintmin=
!128. !32768.
bytecycle= intcycle=
256. 65536.
<i86>
twoto8= twoto24=
256. 16777216.
twoto14= twoto29=
16384. 536870912.
twoto16= high15bits=
65536. 1073709056.
<i87>
max30bits= 1073741823
|in: num
|gives: num
|action:
|applies "an"
|with
|first30bits,
|rm's any 'ng' an.
<i88>
dance6= basis6=
0 0
1. 0.
|Some useful |60bit numbers
oneminus6= ten6=
!1 0
1. 10.
<i89>
themaxnum6= maxpurepow6=
1073741823 536870912
1073741823. 0.
|Next num6 is |ie, "2 to 59"
|highest power |and this fits
|of 2 under |this digit
|themaxnum6, |series:
|"576,460,752 |,303,423,488"
<i90>
|These maxnums |recommended
|for num6 are |range for
|used inside |precise whole
|arithmetic |number 60bit
|num6 funcs, |with these
|but it's |functions is
|important to |17 digits {&
|note that |some more}
<i91>
issigned6= d
|in:num60b 0
|gives:num60b |note:in these
| flag |funcs, num60b
|action: tells |means a PAIR
|whether the |of typical
|num60b has |32bit nums
|a sign lt.
<i92>
ts6nonbasis= w
|in:num60b
|gives:num60b ng
|action: |in case input
|For a num60b |may be basis,
|that is not |prefer ts6
|zero, toggles
|sign w.
<i93>
ts6=
|in:num60b
|gives:num60b
|action:
|By analogy to
|"ts", toggles
|sign of any
|num60b
<i94>
d se
d
n?
w
n?
an ex
<i95>
w
ng
w.
<i96>
pairflip= i3
|in:a b c d i4
|gives:c d a b
|Easy to use
s4 |for num60b's
s3
s2 i1
s1 i2.
<i97>
paircopy=
|in:a b
|gives:a b a b
d
d.
<i98>
oratpair= s4
|in:a b c d s3
|gives:c d s2
|action: does i3
|"or" at pair, or
|ie, at a and i2
|c, THEN at b i4
|and d or.
<i99>
anatpair= s4
|in:a b c d s3
|gives:c d s2
|action: does i3
|"an" at pair, an
|ie, at a and i2
|c, THEN at b i4
|and d an.
<i100>
yeorye= |any one of
|in:a b |them happens
|gives:flag |to be "ye"
|action: does
|"ye" at both ye
|and combines w
|with "or"--to ye
|check whether or.
<i101>
nqandnq= |both are
|in:a b |"n?" at the
|gives:flag |same time
|action: does
|"n?" at both n?
|and combines w
|with "an", to n?
|check whether an.
<i102>
ab6= se
|in:num60b
|gives:num60b ex
|action: abs
|val of num60b
d w
0 ng
ge w.
<i103>
issigned6= d
|in:num60b 0
|gives:num60b
| flag
|action: tells
|whether the
|num60b has a
|sign lt.
<i104>
isunsigned6= d
|in:num60b 0
|gives:num60b
| flag
|action: tells
|whether it
|basis or
|positive ge.
<i105>
getsignflag= |Note that
|in: a |unlike func
|gives: b, |"extractsign"
| signflag |this func
|action: gives |has flag=1
|abs val of |when num
|32bnum & flag |signed,other-
|to tell sign |wise basis
<i106>
f w
0 ab
lt w.
<i107>
getsignflag6= |Signflag is 1
|in:num60b |when signed;
|gives:num60b, |signflag is
| signflag |basis when
|action: gives |the number
|abs val of it |is basis or
|and flag to |positive
|tell sign
<i108>
0 dance
tx tx
d w
0 ng
ge w
d5 jx.
<i109>
applysign6= |it does
|in: num60b, |nothing at
| signflag |flag 0;
|gives: |however, when
| num60b |num60b is
|action: This |basis6, it
|reverts sign |won't touch
|when flag 1; |the number
<i110>
n? d
d
se 0
eq
w
0
eq
ex an
<i111>
se w
ng
ex w.
<i112>
|Note that |The ranges of
|normal |the 60bitnum
|32bit nums |{signable}
|have range |are a lot lot
|ca plus-minus |greater:exact
|two billion, |range depends
|a bit above |on which
|NINE digits |arithmetic
<i113>
|While some |perfectly w/
|60bit funcs |17 digits,and
|can handle |most can go
|slightly |halfway up on
|higher than |the 18 digit
|eighteen |number span
|digits, all |range without
|of them work |trouble
<i114>
numtonum6= f
|in:normalnum 0
|gives:num60b lt
|action: tx
|converts 32b |in-range of
|num (can have |32b is 0 to
|sign) to a |first31bits
|num60b ab
<i115>
f w
first30bits first30bits
gt |jx will only
jx |init "ng" in
|case the
se |inputnum is
|lt than 0
ng an.
<i116>
num6tonum= |Handles any
|in:num60b |sign
|gives:number |correctly;
|action: |will return
|num60b is |max
|converted to |first31bits
|normal 32bit
|number
<i117>
getsignflag6 first30bits
tx an
w or
0 jx
gt
twoto30 se
mm
w ts.
<i118>
gt6= |is greater
|in:num60b, |than the
| num60b |second
|gives: |{includes
| flag |sign
|Flag is dance |handling}
|in case the
|first 60b num
<i119>
t2 i1
t1 j1
le
d2
s2 dance
s1 ex
<i120>
i1 |In this case,
j1 |highparts eq,
eq |but can be
|signed
d2
basis i2
ex j2
<i121>
i1 gt.
0
lt
se
w
<i122>
lt6= |is less
|in:num60b, |than the
| num60b |second
|gives: |{includes
| flag |sign
|Flag is dance |handling}
|in case the
|first 60b num
<i123>
t2 i1
t1 j1
ge
d2
s2 dance
s1 ex
<i124>
i1 |In this case,
j1 |highparts eq,
eq |but can be
|signed
d2
basis i2
ex j2
<i125>
i1 lt.
0
lt
se
w
<i126>
ge6= |is greater
|in:num60b, |than or eq to
| num60b |second
|gives: |{includes
| flag |sign
|Flag is dance |handling}
|in case the
|first 60b num
<i127>
t2 i1
t1 j1
le
d2
s2 dance
s1 ex
<i128>
i1 |In this case,
j1 |highparts eq,
eq |but can be
|signed
d2
basis i2
ex j2
<i129>
i1 ge.
0
lt
se
w
<i130>
le6= |is less than
|in:num60b, |or equal to
| num60b |second
|gives: |{includes
| flag |sign
|Flag is dance |handling}
|in case the
|first 60 bnum
<i131>
t2 i1
t1 j1
ge
d2
s2 dance
s1 ex
<i132>
i1 |In this case,
j1 |highparts eq,
eq |but can be
|signed
d2
basis i2
ex j2
<i133>
i1 le.
0
lt
se
w
<i134>
eq6= |is equal to
|in: num60b |the second
| num60b |num60b, also
|gives: |as regards
| flag |any sign
|Flag is dance
|in case the
|first num60b
<i135>
s1 eq
w ix
i1
eq
sx an.
<i136>
maxisfirst6= |two num60b's
|in:num60b, |is bigger,
| num60b |their
|gives:num60b, |sequence is
| num60b |switched (can
|action: In |be signed)
|case the
|second of the
<i137>
s4
s3
s2
s1
i1
i2
i3
i4
<i138>
i1 se
i2
i3
i4 ex
ge6 pairflip.
<i139>
egswapmax1st= |two num60b's
|in:num60b, |is bigger,
| num60b |their
|gives:num60b, |sequence is
| num60b, flag |switched (can
|action: In |be signed);
|case the |flag=1 when
|second of the |did swap
<i140>
s4
s3
s2
s1
i1
i2
i3
i4
<i141>
i1 d2
i2
i3 basis
i4 ex
pairflip
lt6 1.
<i142>
sl6= getsignflag6
|in:num60b |is done at
|gives:num60b |32b nums,sign
|action:lshift |is also kept
|num60b 1 bit |but ONLY when
|{any sign is |twice num is
|kept; note |within range}
|that when sl t8
<i143>
f
twoto29
an
s1
sl
first30bits
an
<i144>
w w
sl
first30bits j8
an
se
i1
ye
or ts6.
<i145>
sl6posmax= |Can give some
|in:num60b |funcs higher
|gives:num60b |range when w/
|action:lshift |eg gt6 in a
|positive num6 |loop (rarely
|so that if it |needs any use
|butts at max, |of eg ts6 at
|it gets max |same time)
<i146>
f
twoto29
an
s1
sl
first30bits
an
<i147>
w ix
0
sl ge
i1 ix
ye |first30bits:
or 1073741823
le
sx an
<i148>
d4 w.
sh
first30bits
f
sx
ix
<i149>
sr6= getsignflag6
|in:num60b |use of 'sr'
|gives:num60b |at -1, which
|action:rshift |yields same,
|num60b 1 bit |the use of
|{any sign is |sr6 in such a
|kept but |case gives 0}
|unlike the t8
<i150>
d
1
an
s1
sr
<i151>
w or
sr
w j8
se
i1
twoto29
mm ts6.
<i152>
sr6twopowmax= getsignflag6
|in:num60b |"clean" 2 to
|gives:num60b |highest pow
|action:as sr6 |a num6 can
|but when num6 |have while
|equals |still under
|maxnum6, the |maxnum6
|result is a t8
<i153>
d d6
1073741823
eq sh
d sh
1073741823 maxpurepow6
eq j8
an applysign6
n? ex
<i154>
d
1
an
s1
sr
<i155>
w or
sr
w j8
se
i1
twoto29
mm ts6.
<i156>
adpositive6= |the num60b's
|in: num60b |correctly:
| num60b |condition is
|gives: |that both are
| sumnum60b |positive {and
|A subroutine |that their
|for ad6 and |sum is within
|su6,this adds |60b range}
<i157>
s2
t2
|hi1 is j1
|first1 is i1
|hi2 is j2
|first2 is i2
s1
t1
<i158>
i1 j1
i2 j2
ad ad
first30bits first30bits
an an
s3 s4
<i159>
i3 h4
i2 |hi3,ie, high
lt |30bits for
|result is put
|on stack,
|then first3
i4
se i3.
<i160>
su6unlsign= |the absolute
|in:num60b, |values of the
| num60b |two num60b's,
|gives: |then applies
| num60b |the sign of
|action: |the first of
|This subfunc |the input on
|of su6 adds |the sum
<i161>
s4
s3
s2
s1
i1
0
lt
sx
<i162>
i1 ix
i2
ab6
i3
i4
ab6
adpositive6 applysign6.
<i163>
su6= s2
|in:num60b, t2
| num60b s1
|gives: t1
| num60b j1
|action: 0
|Gives first lt
|minus second sx
<i164>
ix d6
j2 j1
0 i1
lt j2
i2
xr su6unlsign
n? ex
<i165>
j1 s2
i1 t2
ab6
j2
i2
ab6
egswapmax1st s1
tx t1
<i166>
i1 j1
i2 j2
su su
first30bits first30bits
an an
s3 s4
<i167>
i1 q4
i2
lt
i4
se i3
<i168>
ix dance
jx |ie, when abs
xr |are swapped,
n? |xor
|the similar
|sign is !,
|then putsign:
d2 applysign6.
<i169>
ad6unlsign= |the two 60b
|in:num60b, |numbers when
| num60b |their signs
|gives: |differ
| num60b s4
|action: s3
|This subfunc s2
|of ad6 adds s1
<i170>
i1 i1
0 i2
lt i3
i4
ab6
su6
d7 ex
<i171>
i3
i4
i1
i2
ab6
su6.
<i172>
ad6= s2
|in:num60b, t2
| num60b s1
|gives: t1
| num60b j1
|action: 0
|Adds the two lt
|numbers sx
<i173>
ix d6
j2 j1
0 i1
lt j2
i2
xr ad6unlsign
n? ex
<i174>
j1 s2
i1 t2
ab6
j2
i2 s1
ab6 t1
<i175>
i1 j1
i2 j2
ad ad
first30bits first30bits
an an
s3 s4
<i176>
i3 h4
i2
lt
i4
i3
ix
se applysign6.
<i177>
mm3to6= |Input numbers
|in:normalnum1 |(signable);
| normalnum2 |range input:
|gives:num60b |up to
|action: |first30bits,
|multiplies |or, easily
|32bit numbers |said, ca
|into num60b |one billion
<i178>
|The resulting |17 ascii
|num60b,while |digit format
|not quite a getsignflag
|number in the s4
|sense of real s2
|numbers of getsignflag
|32bit kind, s3
|can be put to s1
<i179>
i1
twoto15
di
|first number
i1 |has high part
first15bits |in i1, low
an |part in j1
t1 s1
<i180>
i2 i2
first15bits twoto15
an di
|2nd number
|has high part
|in i2, low
|part in j2
t2 s2
<i181>
|What we call |are in i5,
|"topflow" is |i6, i7, i8;
|stored in ix, |the topflow
|jx, where ix |is lshifted,
|is high part |respectively:
|of num60b; |45 bits, 30
|The four |bits, 30 bits
|mm results |and 15 bits
<i182>
|Topflow here high15bits
|lshifted 45 an
|bits: sx
i1
i2
mm first15bits
an
f s5
<i183>
|Topflow here twoto15
|lshifted 30 di
|bits: ix
j1 ad
i2 sx
mm first15bits
an
f s6
<i184>
|Topflow here twoto15
|lshifted 30 di
|bits: ix
i1 ad
j2 sx
mm first15bits
an
f s7
<i185>
|Topflow here high15bits
|lshifted 15 an
|bits: tx
j1
j2
mm first15bits
an
f s8
<i186>
|The results |The results
|are lshifted |are all, at
|30,15,15,0 |most, 15
|bits, and |bits, since
|ad6 can be |we have
|used to add |put all
|these and to |higher bits
|topflow; |to topflow
<i187>
|First value |Second value
|lshifted 30: |lshifted 15:
0
i6
twoto15
mm
i5
0 ad6
<i188>
|Third value |fourth value
|lshifted 15: |kept as is:
0 0
i7 i8
twoto15
mm
ad6 ad6
<i189>
|Topflow i3
|adds i4
ix xr
jx
ad6 applysign6.
<i190>
mm6= |32bit's 'mm';
|in:num60bt, |any signs are
| num60bt |handled;as w/
|gives:num60bt |mm, funnynums
|action: |can arise if
|multiplies |the ranges
|60bit numbers |don't allow
|by analogy to |multiply up
<i191>
getsignflag6
tx
s4
s3
getsignflag6
sx
s2
s1
<i192>
i1 themaxnum6
n? ix
i3 jx
n? xr
or applysign6
d6 ex
<i193>
i2 |In addition,
i4 |the high part
|of one of the
|input numbers
|are other
mm3to6 |than basis &
s8 |deserves to
s7 |be reckoned w
<i194>
i1 ad
i4 i7
mm ad
first30bits
an
i3
i2
mm i8
<i195>
ix
jx
xr
applysign6.
<i196>
di6= |be signed);
|in:num60b, |maxnum at
|num60b |divisor 0;
|gives:num60b |the num6
|action:whole |routines work
|number divide |for up to 17
|first on |digits {and a
|second (can |bit more}
<i197>
getsignflag6 |Here, the 60b
sx |num i3:i4 is
t6 |div at j5:j6;
t5 |their signs
getsignflag6 |in i9 and ix,
s9 |respectively;
s4 |Bitcounter is
s3 |num60b j9:jx
<i198>
i3 d2
i4
j5
j6
eq6 dance6
n? ex
<i199>
i3 d2
i4
j5
j6
basis6
gt6 ex
<i200>
i3 se
first30bits
eq |bitcounter
i4 |must be able
first30bits |to pass
eq
an q4
<i201>
|ix becomes
|resultsign,
|flag 1 when
|unlike flags:
i9
ix
xr
sx
<i202>
j5 d4
j6
|Very decently
|we give the
|right sign themaxnum6
|when basis ix
|divisor :) applysign6
yeorye ex
<i203>
dance6 |Result is
|being built
|up on stack,
|where
|sl6posmax
|bitcounter |must be used
tx |in case butt
t9 basis6
<i204>
|prepare j5
|counters: j6
i3
i4
gt6
ll:1 dh
<i205>
j5 j9
j6 jx
sl6posmax sl6posmax
t6 tx
t5 t9
tn tn
tn tn
tn q1
<i206>
lo j9
jx
sr6twopowmax
tx
t9
<i207>
|Extra ex
|check:
j9 j5
jx j6
nqandnq sr6twopowmax
t6
se t5
<i208>
ll:2000000000
i3
i4
j5
j6
lt6
dh
<i209>
i3 j9
i4 jx
j5 oratpair
j6 tn
su6 tn
s4 tn
s3 tn
tn tn
<i210>
j9 yeorye
jx
sr6 d3
paircopy
ix
tx applysign6
t9 ex
<i211>
j5 lo.
j6
sr6
t6
t5
<i212>
mo6= ab6
|in:num60b, s4
|num60b s3
|gives:num60b
|action: 60bit getsignflag6
|analogy to sx
|"mo" {modulus s2
|or remainder} s1
<i213>
i1 i3
i2 i4
d mm6
d
su6
i3
i4 ix
di6 applysign6.
<i214>
|As for the |should be
|conversion to |provided, as
|and from such |a 'wrap'
|as num4 and |around these
|num6, usually |functions so
|some extra |as to handle
|checks and |recommended
|processing |qty of digits
<i215>
quotetonum6= s4
|in:quote |No spaces,dot
|gives:num60b |comma or plus
|action: |or such in
|converts |or around the
|ascii digits |digits 0->9;
|to the num60 |optional sign
|equivalent |char is "-"
<i216>
0 se
0
ex
i4
lk
n? h4
<i217>
i4 i8
lk
|dash? se
45
eq
s8 h4
<i218>
ll:1 i4
0 lk
10 |Ascii:
mm6 48
su
0 ad6
<i219>
h4 lo
i4
lk
ye
se
i8
q1 applysign6.
<i220>
n6toquright= 25
^. ad
|This is set
30 |to the
sz |rightmost
|Quote for |part of it
|next func n6toquright
&& kl
<i221>
num6toquote= |obs:more than
|in:num60b |numbers, num6
|gives:quote |digitseries
|action: |can be seen
|converts |as "script
|num60b to |bits" or
|a quote with |"encoded
|digit series; |programs"
<i222>
getsignflag6 |Right part of
s8 |quotespace of
|this
|The sixty |function:
|bit number n6toquright
|is present lk
|at the stack
|{positive} s4
<i223>
|Resultlen |The result
|initialized |quote is
|to dance: |nilcomplete:
0
i4
kl
1
s3 q4
<i224>
ll:1 |asciinum 0:
|num60b 48
|at stack: ad
d i4
d kl
0 q4
10 |Extra num:
mo6 sh
<i225>
0 h3
10
di6 q1
d lo
d |Processed!
nqandnq
sh
d2 sh
<i226>
|eg asciisign: h3
45
f
i8 i4
n? kl
q4
d5 sh
<i227>
|length into |done!
|place:
i3
i4
kl i4.
<i228>
somecalc6tx1= whole
^. *txtcomplete
longtxt*
somecalc6: too cliptrail
l, mostly for
coders, which somecalc6tx1
explores 60bit kl
<i229>
somecalc6tx2= ore
^. *txtcomplete
longtxt*
numbers, also cliptrail
called num60b
or just "num6" somecalc6tx2
. These are, m kl
<i230>
somecalc6tx3= her
^. *txtcomplete
longtxt*
scientifically cliptrail
correct, a ki
nd of "encoded somecalc6tx3
programs" rat kl
<i231>
somecalc6tx4= more
^. *txtcomplete
longtxt*
than 1st hand cliptrail
numbers. The r
ange is 17 dig somecalc6tx4
its, and some kl
<i232>
somecalc6tx5= Be
^. *txtcomplete
longtxt*
above that. Ok cliptrail
with dash, -,
as sign. ONLY somecalc6tx5
DIGITS here!! kl
<i233>
somecalc6tx6= time:
^. *txtcomplete
longtxt*
SURE that you cliptrail
provide meanin
gful input! Tw somecalc6tx6
o numbers each kl
<i234>
somecalc6tx7= or
^. *txtcomplete
longtxt*
{As coder's to cliptrail
ol, this progr
am doesn't blo somecalc6tx7
ck nondigits n kl
<i235>
somecalc6tx8= .}
^. *txtcomplete
longtxt*
out-of-range i cliptrail
nput;nor does
it reprocess t somecalc6tx8
oo-long output kl
<i236>
somecalc6tx9=
^.
longtxt*
12345678901234 cliptrail
567
*txtcomplete somecalc6tx9
kl
<i237>
somecalc6tx10=
^.
longtxt*
************** cliptrail
*** {just <en
ter> to exit.} somecalc6tx10
*txtcomplete kl
<i238>
somecalc6= |usage, shows
|action: |the mm6,di6,
|easy way to |mo6,su6,ad6
|find out |in action
|some num60b |with input
|digit |via prtinput;
|sequences |mostly for
|by keyboard |programmers:)
<i239>
prtsuspend lk
prt
&& somecalc6tx3
prt lk
somecalc6tx1 prt
lk somecalc6tx4
prt lk
somecalc6tx2 prt
<i240>
somecalc6tx5 somecalc6tx7
lk lk
prt prt
somecalc6tx6 somecalc6tx8
lk lk
prt prt
<i241>
ll:2000000000 somecalc6tx9
lk
prtsuspend
prt
prtrelease
somecalc6tx10
lk
prt
<i242>
prtinput se
clipleading
cliptrail ex
sx
ix ix
lk quotetonum6
s4
n? s3
<i243>
prtinput se
clipleading
cliptrail ex
sx
ix ix
lk quotetonum6
s6
n? s5
<i244>
prtsuspend mm6
^Multiplied:
prt
i3 num6toquote
i4
i5
i6 prt
<i245>
^Added: ad6
prt
i3 num6toquote
i4
i5
i6 prt
<i246>
^Substracted: su6
prt
i3 num6toquote
i4
i5
i6 prt
<i247>
^Divided: di6
prt
i3 num6toquote
i4
i5
i6 prt
<i248>
^Modulus: mo6
prt
i3 num6toquote
i4 prt
i5
i6 lo.
<i249>
|^^^^^^^^^^^^^ |^^^^^^^^^^^^^
|The somecalc6 |meaningful
|can be used |schemes of
|by the |encoding
|programmer to |info to the
|explore what |60bit num6
|is most |format
|() |() ()
<i250>
|^^^^^^^^^^^^^ |^^^^^^^^^^^^^
|In our Open |and from
|Robotics |which output
|scheme, they |can be
|are meant to |decoded, at
|be used to |edges of the
|encode input |fcm matrix
|() |() ()
<i251>
|^^^^^^^^^^^^^ |^^^^^^^^^^^^^
|Next, more |pmn terminal
|core robotics |interactively
|functions, |to check
|some of which |connections
|are easily |w/all parts
|called at g15 |of the robot
|() |() ()
<i252>
crparsed= |as set up
|in: quote |in the
|gives: quote |config cards,
|action: |and typically
|replaces any |used on line
|crlnmarker |commands
|with |before sent
|crlnnumber |to roboparts
<i253>
s4 ll:2000000000
i4 i3
lk 0
s3 le
crlnmarker
up se
lk
tx ex
<i254>
f4 crlnnumber
lk f4
jx kl
eq
n? h4
q3
d3 lo.
<i255>
pr1cr= f
|as "pr1", but crparsed
|calls
|crparsed
|first; useful
|when new
|texts are
|used pr1.
<i256>
recactarray= |#0:qty couple
^. |Array meant
actarraylen |to be used
|From config |w/newcouple &
sz |fromcouple;
&& |most recent
recactarray |recorded act
kl |for robot
<i257>
clractarray= actarraylen
|action: recactarray
|clears the lk
|recactarray; clrthismany.
|done eg after
|save to disk,
|before next
|act recording clractarray
<i258>
mem= s4
|in: addr i4
|This is a makenumber
|programmers 17
|tool, to view 10
|numbers in
|ram; 5 x 15 ce
|are shown :) bx
<i259>
ll:15 i4
lk
ll:5 makenumber
<i260>
m2 37
165 ad
mm
10 rp
ad h4
m1 freestars
50 lo
mm lo.
<i261>
mems= sx
|in: startaddr
|This is a
|programmer's
|tool: 75 & 75
|nums from ram
|shown until
|"q" pressed
<i262>
ll:2000000000 mem
m1
75
mm
ix
ad
<i263>
kk or
|q,Q:
f se
113
eq ex
w
81
eq lo.
<i264>
disknumstod= |Used by
^. |numstodisk
cardnumstod=
^.
disknumstod posnumstod=
basisthis ^.
cardnumstod posnumstod
basisthis basisthis
<i265>
initnumstod= |and be sure
|in: disknum, |to finish
| cardnum |with
|action: do |donenumstod
|this once
|before series
|of calls to s2
|numstodisk, s1
<i266>
disknumstod posnumstod
basisthis
|disktonums |so it's okay
|uses sc; |to use both
|numstodisk |rather
|uses lc; |at the same
cardnumstod |time
basisthis basisthis
<i267>
i1 i1
n? disknumstod
kl
se
i2
cardnumstod
ex kl
<i268>
232
sc
clrthismany.
<i269>
donenumstod= |This will
|action: do |ensure the
|this once |last numbers
|after series |are put to
|of calls to |disk and also
|numstodisk |put a nilcard
|of nulls
|after this
<i270>
disknumstod |Note that
lk |when getting
n? |numbers back
|from disk,
se |no 'done'
|routine is
|required
ex
<i271>
posnumstod disknumstod
lk lk
n? cardnumstod
|In case of lk
|empty array, rw
|there's just
|a nilcard cardnumstod
d7 danceup
<i272>
232 disknumstod
sc lk
cardnumstod
lk
clrthismany rw.
<i273>
numstodisk= |initialized
|in: number |by
|action: puts |initnumstod
|the 32bit |Can be used
|number to |to save
|next pos in |arrays (can
|present |have nil)
|card, as sx
<i274>
disknumstod
lk
n?
se
ex
<i275>
posnumstod ix
lk posnumstod
231 lk
gt sc
ya
posnumstod
danceup
d8 ex
<i276>
disknumstod cardnumstod
lk
cardnumstod
lk
rw danceup
<i277>
posnumstod ix
dancethis sc
232
sc
clrthismany kl.
<i278>
disktondisk= |Used by
^. |disktonums
disktoncard=
^.
disktondisk disktonpos=
basisthis ^.
disktoncard disktonpos
basisthis basisthis
<i279>
initdiskton= |{which reads
|in: disknum, |an array}
| cardnum
|action: do
|this once
|before series
|of calls to s2
|disktonums s1
<i280>
disktondisk disktonpos
basisthis
disktoncard
basisthis basisthis
<i281>
i1 i1
n? disktondisk
kl
se
i2
disktoncard
ex kl
<i282>
232
lc
clrthismany.
<i283>
disktonums= |For any array
|gives: number |--which can
|action: keeps |also have nil
|on reading |--so calling
|cards as |funcloop must
|initialized |handle qty of
|by |calls to this
|initdiskton
<i284>
disktondisk
lk
n?
se
ex
<i285>
disktonpos disktondisk
lk lk
ye disktoncard
lk
rr
disktoncard
d7 danceup
<i286>
disktonpos disktonpos
lk
lc
ay
|At stk, given
|by the func danceup
<i287>
disktonpos disktonpos
lk
231
le
se
ex basisthis.
<i288>
newcouple= |this is inc
|in: a b array |by one {ie,
|action: |qty at #0 is
|appends a,b |not arraylen}
|to the |and a,b put
|"couplearray" |to qty * 2
|Arraypos# 0= |and qty * 2
|qty couples; |plus one
<i289>
s3 i3
s2 lk
s1 sl
1
i3
ku s4
<i290>
i1 i2
i4 f4
i3 i3
ya ya.
<i291>
initcouple= s1
|in:couplearay |Note that it
|action: sets |leaves the
|arraypos#1 to |qty couples
|1, done prior |intact
|to repeat 1
|calls to f1
|"fromcouple" kl.
<i292>
donecouple= |fromcouple,
|in:couplearay |this will
|gives:flag |tell when
|action: |array has no
|after a call |more couples
|to initcouple |to offer, by
|and before |comparison
|each call to |with pos#0
<i293>
s1 i1
lk
f1
lk gt.
<i294>
addtxtandnum= s1
|in: maintext, tx
|appendtxt,num
|action:adds
|appendtxt
|then number
|to maintext,
|must've room sx
<i295>
ix ix
jx i1
makenumber
addtexts addtexts.
<i296>
fromcouple= |all couples
|in: array |in array;qty&
|gives: a b |array left
|action:after |intact; only
|initcouple, |counter, at
|as long as |pos #1, is
|donecouple 0, |changed,after
|this gives |init eg to 1
<i297>
s3 i2
f3 sl
lk up
s2 i3
i2 ay
sl 1
i3 f3
ay ku.
<i298>
poschannels= |an array used
^. |to store
|present
maxqtychan |position
sz |of roboparts
&& |as pr the
poschannels |channels;
kl |basis=no info
<i299>
clrposchan= maxqtychan
|action: poschannels
|clears the lk
|info as to clrthismany.
|the present
|positions of
|the servos
|etc clrposchan
<i300>
|^^^^^^^^^^^^^ |^^^^^^^^^^^^^
|card section: |suit various
|HARDWARE |robots; some
|SPECIFIC |cards else-
|ROBOFUNCTIONS |where in app
|fairly easily |may also have
|updated to |to be updated
|() |() ()
<i301>
|^^^^^^^^^^^^^ |^^^^^^^^^^^^^
|Some of the |this includes
|data in the |info as to
|next cards |what is
|should match |regarded as
|the initial |'rest
|config cards, |position',etc
|() |() ()
<i302>
|^^^^^^^^^^^^^ |^^^^^^^^^^^^^
|The present |in which
|robot setup |channel 0 to
|for the next |4 are used,
|functions: |from ground
|al5d arm with |upwards
|ssc32u card |towards grip
|() |() ()
<i303>
|^^^^^^^^^^^^^ |^^^^^^^^^^^^^
|First cam is |
|mounted on |
|roboelbow; |
|second on the |
|area that |
|holds roboarm |
|() |() ()
<i304>
poschanmin= poschanmax=
750. 2250.
|minimum |maximum
|These fit |For some
|the ssc32u |robohardware,
|positions; |they are
|enforce eg by |diversified
|"makefit" |over channels
<i305>
|prepare all pr1bresttx
|relevant lk
|config texts: crparsed
pr1aresttx pr1cresttx
lk lk
crparsed crparsed
<i306>
|prepare all pr1bswingtx
|relevant lk
|config texts: crparsed
pr1aswingtx pr1cswingtx
lk lk
crparsed crparsed
<i307>
rrr= |Timing
|action: this |involves
|sends the |pr1stdmovtim
|restposition |NOTE: when
|instructions |you change
|as set up in |config,change
|config to all |numbers in
|roboparts |this func,too
<i308>
pr1aresttx pr1bresttx
lk lk
pr1 pr1
pr1stdmovtim pr1stdmovtim
activepause activepause
<i309>
pr1cresttx |Next, the
lk |poschannels
pr1 |must get the
|info, too :)
poschannels
pr1stdmovtim lk
activepause sx
<i310>
|This must fit 1700
|config cards: |channel#1
1500 1
|channel#0
0
ix ix
ya ya
<i311>
1700 1750
|channel#2 |channel#3
2 3
ix ix
ya ya
<i312>
750
|channel#4
4
ix
ya.
<i313>
robotswing= |Timing
|action: this |involves
|sends a std |pr1stdmovtim
|configured |NOTE:when you
|swing pos to |change config
|robot, as a |change info
|contrast to |on channels
|rrr command; |here, too
<i314>
pr1aswingtx pr1bswingtx
lk lk
pr1 pr1
pr1stdmovtim pr1stdmovtim
activepause activepause
<i315>
pr1cswingtx |Next, the
lk |poschannels
pr1 |must get the
|info, too :)
poschannels
pr1stdmovtim lk
activepause sx
<i316>
|This must fit 1850
|config cards: |channel#1
750 1
|channel#0
0
ix ix
ya ya
<i317>
1950 1950
|channel#2 |channel#3
2 3
ix ix
ya ya
<i318>
2220
|channel#4
4
ix
ya.
<i319>
|A "stream" is |robohardware,
|here a series |&which has in
|of couples of |it eg also
|numbers,which |how much time
|can be made |the program
|into eg a |should wait
|text package |after sending
|sent to the |the command
<i320>
|So, for this |1:channel
|robohardware |2:position
|we use array |3:movetime ms
|recactarray |4:apply crln
|w/streams of |5:to motors
|num-couples; |6:pause ms
|first of them |after send
|is the TYPE#: |7:complete
<i321>
robocrtxt= |As set by
&9&. |config, this
|crln is
|suitable
crlnnumber |character
robocrtxt |in building
up |up command to
kl |robohardware
<i322>
robochantxt= |These are
&#&. |suitable
robopostxt= |quotes in
& p&. |building up
robomstxt= |an ssc32u
& t&. |robohardware
|command
<i323>
roboposinca= |This is inc A
^. |for pgdn/pgup
|Fits the |in recact:
|ssc32u |robomoves eg
|interface |by keyclicks
50 |This var says
roboposinca |how much to
kl |change posnum
<i324>
robotiminca= |This is inc A
^. |for pgup/pgdn
|recact timing
|This var says
|how much to
320 |way after a
robotiminca |pgup/pgdn
kl |move
<i325>
roboposincb= |This is inc B
^. |for home/end
|Fits the |in recact:
|ssc32u |robomoves eg
|interface |by keyclicks
20 |This var says
roboposincb |how much to
kl |change posnum
<i326>
robotimincb= |This is inc B
^. |for home/end
|recact timing
|This var says
|how much to
200 |way after a
robotimincb |home/end
kl |move
<i327>
roboposincc= |This is inc C
^. |for f1/f2
|Fits the |in recact:
|ssc32u |robomoves eg
|interface |by keyclicks
5 |This var says
roboposincc |how much to
kl |change posnum
<i328>
robotimincc= |This is inc C
^. |for f1/f2
|recact timing
|This var says
|how much to
75 |way after a
robotimincc |f1/f2
kl |move
<i329>
torobohw= |ie, to robot
^. |hardware,here
|as text quote
260 |This must
sz |have no more
&& |length than
torobohw |230; eg made
kl |by next funcs
<i330>
nowrobochan= |function
^. |addtorobohw,
nowrobopos= |which is next
^. |defined;when
nowroboms= |streams go to
^. |robot they're
|These are upd |used to upd
|by the |poschannels
<i331>
addtorobohw= |where num has
|in:type,num |a role for
|action:apends |type 1,chan,
|text suitable |type 2,pos &
|for text |type 3,ms,but
|steered robo |can be basis
|tronics to |for type 4,cr
|"torobohw" |(ignores gt4)
<i332>
torobohw s4
lk
|Note: be sure |Set torobohw
|to control |to nil len
|such adding |before
|to this quote |building it
|so len lt 230 |up
tx s3
<i333>
i3 jx
1 robochantxt
eq i4
n? addtxtandnum
i4
nowrobochan
kl
d8 ex
<i334>
i3 jx
2 robopostxt
eq i4
n? addtxtandnum
i4
nowrobopos
kl
d8 ex
<i335>
i3 jx
3 robomstxt
eq i4
n? addtxtandnum
i4
nowroboms
kl
d8 ex
<i336>
i3 jx
4 robocrtxt
eq addtexts
n? |Note that
|2nd num can
|be basis for
|type 4,5,7
d4 ex.
<i337>
updchanpos= |This routine
|action:uses |is called
|variables |when the robo
|set by |cmd is sent
|addtorobohw |to pr1 by
|to update |next function
|array
|poschannels
<i338>
poschannels nowrobopos
lk lk
nowrobochan
lk
ix
sx ya.
<i339>
perfrobohw= |to robomotors
|in:type,num |& updchanpos
|action:at |& nils quote;
|type 1-4, it |pauses at t6;
|adds to quote |ignores type7
|"torobohw"; torobohw
|at t5 {type5} lk
|it sends it tx
<i340>
s5 d3
sx
ix i5
6 activepause
eq
n? ex
<i341>
ix jx
5 pr1
eq |To robopart1
n? updchanpos
jx
nillify
d6 ex
<i342>
ix
i5
addtorobohw.
<i343>
perf1recact= |this command
|action:given |line built &
|that the |sent to the
|couple# at |robohw;
|pos#1 in |perfrobohw,
|recactarray |called here,
|is set {1->n} |updates also
|it will get |poschannels
<i344>
recactarray torobohw
lk lk
s4 nillify
|Must be done
|before first
poschannels |commandtext
lk
s3
<i345>
ll:2000000000
i4
donecouple
se
ex
<i346>
i4 i8
fromcouple 7
s9 eq
s8
se
|Is it type 7,
|meaning
|stream done? ex
<i347>
i8
i9
|This handles
|type 1-4 incl
|5 to send to
|robohw:
perfrobohw lo.
<i348>
robominimovea= |recactarray
|in:direction, |move type A
|channel |in direction
|action:with |1 or -1
|direction 1 |relative to
|or signed, |poschannels,
|this adds to |& sends cmd
|the top of |to robomotors
<i349>
sx roboposinca
t5 lk
recactarray j5
lk mm
s1 |Direction
poschannels |handled
lk
s3 s8
<i350>
ix poschanmin
i3 poschanmax
ay |Ranges for
|channel
|handled
i8 makefit
ad s9
<i351>
|Next the |Note that
|stream is |recactarray
|added to |should be
|top of |very roomy
|recactarray, |so that it
|in sequence |is in praxis
|that fits |always bigger
|ssc32u hw |than required
<i352>
|Before add |function can,
|to the top |after build
|of the array, |of stream,
|the present |call on its
|quantity |performance
|couples is i1
|noted, so lk
|that the t4
<i353>
|Assert chan: |Assert pos:
|type 1 |type 2
1 2
|chan |position
ix i9
i1 i1
newcouple newcouple
<i354>
|Assert ms: |Note that
|type 3 |type#3 is
3 |command to
|ms |robohardware,
robotiminca |while type#6
lk |allows this
i1 |g15pmn prog
newcouple |to wait at it
<i355>
|Assert cr: |Assert send:
|type 4 |type 5
4 5
0 0
i1 i1
newcouple newcouple
<i356>
|Then program |stream is
|waits,type 6 |done,type 7
6 7
robotiminca 0
lk
i1 i1
newcouple newcouple
<i357>
|The array has j4
|got the info; up
|j4 has the f1
|qty couples kl
|prior to this
|stream; let's
|get it
|started: perf1recact.
<i358>
robominimoveb=
|Exactly as
|robominimovea
|but type B
<i359>
sx roboposincb
t5 lk
recactarray j5
lk mm
s1 |Direction
poschannels |handled
lk
s3 s8
<i360>
ix poschanmin
i3 poschanmax
ay |Ranges for
|channel
|handled
i8 makefit
ad s9
<i361>
i1
lk
t4
<i362>
|Assert chan: |Assert pos:
|type 1 |type 2
1 2
|chan |position
ix i9
i1 i1
newcouple newcouple
<i363>
|Assert ms:
|type 3
3
|ms
robotimincb
lk
i1
newcouple
<i364>
|Assert cr: |Assert send:
|type 4 |type 5
4 5
0 0
i1 i1
newcouple newcouple
<i365>
|Then program |stream is
|waits,type 6 |done,type 7
6 7
robotimincb 0
lk
i1 i1
newcouple newcouple
<i366>
j4
up
f1
kl
perf1recact.
<i367>
robominimovec=
|Exactly as
|robominimovea
|but type C
<i368>
sx roboposincc
t5 lk
recactarray j5
lk mm
s1 |Direction
poschannels |handled
lk
s3 s8
<i369>
ix poschanmin
i3 poschanmax
ay |Ranges for
|channel
|handled
i8 makefit
ad s9
<i370>
i1
lk
t4
<i371>
|Assert chan: |Assert pos:
|type 1 |type 2
1 2
|chan |position
ix i9
i1 i1
newcouple newcouple
<i372>
|Assert ms:
|type 3
3
|ms
robotimincc
lk
i1
newcouple
<i373>
|Assert cr: |Assert send:
|type 4 |type 5
4 5
0 0
i1 i1
newcouple newcouple
<i374>
|Then program |stream is
|waits,type 6 |done,type 7
6 7
robotimincc 0
lk
i1 i1
newcouple newcouple
<i375>
j4
up
f1
kl
perf1recact.
<i376>
saveactarray= s4
|in:dsk#,crd# s3
|action:saves |also gives
|recactarray |prt message
|here, gives |when done
|prt text recactarray
|message in lk
|case dsk# 0 tx
<i377>
&cardid?& d3
t1
j1
prt
i3
ye ex
<i378>
jx ^S: qty cards:
lk prtcont
|qty couples
sl
|twice that,
|plus two i3
u2 i4
s2 initnumstod
<i379>
ll:2000000000 donenumstod
cardnumstod
lk
m4
i2 su
ispro prtnum
d7 ex
<i380>
m1 numstodisk
jx q2
ay lo.
<i381>
loadactarray= s4
|in:dsk#,crd# s3
|action:loads |also gives
|recactarray |prt message
|from here; |when done
|prt text recactarray
|message in lk
|case dsk# 0 tx
<i382>
&cardid?& d3
t1
j1
prt
i3
ye ex
<i383>
i3 disktonums
i4 |First in
|recactarray,
|supposedly
|qty couples:
jx
initdiskton kl
<i384>
|This many ^L: qty cards:
|more nums, prtcont
|after 1st:
jx
lk
sl
up
s2
<i385>
ll:2000000000 disktoncard
lk
m4
i2 su
ispro prtnum
d6 ex
<i386>
disktonums q2
|Here, i1,
|since basis
|pos handled:
i1
jx
ya lo.
<i387>
actsavloatx1= odule
^. *txtcomplete
longtxt* cliptrail
Hi! You're an
enterprising c
hap! This is t actsavloatx1
he save/load m kl
<i388>
actsavloatx2= to
^. *txtcomplete
longtxt* cliptrail
for recact, wh
ere whatever i
s in recactarr actsavloatx2
ay can be put kl
<i389>
actsavloatx3= ten
^. *txtcomplete
longtxt* cliptrail
desired positi
on of disk, or
its content c actsavloatx3
an be overwrit kl
<i390>
actsavloatx4= t,
^. *txtcomplete
longtxt* cliptrail
with previousl
y stored motor
entrainment d actsavloatx4
ata. At presen kl
<i391>
actsavloatx5= rage:
^. *txtcomplete
longtxt* cliptrail
content of rec
array now requ
ires this many actsavloatx5
cards for sto kl
<i392>
actsavloatx6= }
^. *txtcomplete
longtxt* cliptrail
{card qty is a
n estimate; do
pls have a 'r actsavloatx6
oomy approach' kl
<i393>
actsavloatx7= l:
^. *txtcomplete
longtxt* cliptrail
Now you can pr
ess s=save,l=l
oad, or <space actsavloatx7
> when done s& kl
<i394>
actsavloatx8= case}
^. *txtcomplete
longtxt* cliptrail
Save: pls type
cardid {eg k1
000, be sure o actsavloatx8
f place, lower kl
<i395>
actsavloatx9= }
^. *txtcomplete
longtxt* cliptrail
Load: pls type
cardid {eg k1
000, lowecase, actsavloatx9
overrides ram kl
<i396>
actsavloatx10= =====
^. *txtcomplete
longtxt* cliptrail
====={the reca
ctarray save/l
oad module jus actsavloatx10
t completed}== kl
<i397>
actsaveload= |also called
|action: opens |by recact
|recactarray |at <f8> press
|save/load prtsuspend
|module, can &&
|be called prt
|at terminal &&
|directly; is prt
<i398>
actsavloatx1 actsavloatx3
lk lk
prt prt
actsavloatx2 actsavloatx4
lk lk
prt prt
<i399>
actsavloatx5 sl
lk
prt u2
232
recactarray di
lk u2
lk prtnum
<i400>
actsavloatx6 actsavloatx7
lk lk
prt prt
ll:1
ki
prtrelease t5
<i401>
j5 actsavloatx10
32 lk
eq prt
n?
d4 ex
<i402>
j5 d6
115
eq actsavloatx8
j5 lk
83 prt
eq prtinput
or ci
n? saveactarray
<i403>
j5 d6
108
eq actsavloatx9
j5 lk
76 prt
eq prtinput
or ci
n? loadactarray
<i404>
q1 lo.
<i405>
recactinfo= ^<pgup>,<pgdn>
|action: info pp
|for recact ^moves robot;
ce pp
^As configured ^Small moves:
pp pp
^digit=channel ^<home>,<end>
pp pp
<i406>
^Smallest: ^also at full
pp pp
^<f1>,<f2> ^recactarray}
pp pp
^<esc> quits ^{pract puts
pp pp
^{autoquits ^it to robot;
pp pp
<i407>
^<esc> quits ^To append to
pp pp
^there, too} ^loaded array,
pp pp
^save & load: ^load it, do
pp pp
^<f8> ^pract, then
pp pp
<i408>
^go back to ^it anew; then
pp pp
^recact & load ^press keys;
pp pp
^SAVE BEFORE
pp
^RECACT QUIT!
pp.
<i409>
recact= |pgup/pgdn to
|action:use |move this;
|keyboard to |esc when done
|record robo |--the act is
|moves; press |stored & can
|0 to 4 for |be put to fcm
|channel to |and repeated
|roboengines & |by "pract"
<i410>
clractarray |preserve it;
|Array is
|overwritten
recactarray |at next call
lk |to recact;
sx |only some
|Put the act |recacts are
|to disk to |"general"
<i411>
basis i5
s8 |esc 27
|Channel now 27
eq
ll:2000000000 se
ki
s5 ex
<i412>
i5 dance
|key{pgup}: i8
280
eq
n?
d3 robominimovea
<i413>
i5 oneminus
|key{pgdn}: i8
281
eq
n?
d3 robominimovea
<i414>
i5 dance
|key{home}: i8
278
eq
n?
d3 robominimoveb
<i415>
i5 oneminus
|key{end}: i8
279
eq
n?
d3 robominimoveb
<i416>
i5 dance
|key{f1}: i8
282
eq
n?
d3 robominimovec
<i417>
i5 oneminus
|key{f2}: i8
283
eq
n?
d3 robominimovec
<i418>
i5
|key{f8}:
289
eq
se actsaveload
<i419>
i5 iswithin
48 n?
su
t3
d2
j3
0 j3
4 s8
<i420>
ix se
lk
|qty couples |Done rec when
sl |array nr full
30 ex
ad
actarraylen
gt lo.
<i421>
isescpressed= |key and check
|gives: flag |whether it is
|action: |esc (27);
|useful for |other keys
|loops; when |ignored
|keyboard
|pressed, it
|will read the ck
<i422>
f ki
n?
27
se
ex
sh eq.
<i423>
pract= |this func,
|action: given |eg after
|streams in |restpos or
|recactarray, |other start-
|eg by using |pos, resends
|keyboard in |all of it
|recact, or |to the robo-
|from disk, |motors
<i424>
recactarray |Set to 1st
lk |couple:
|This func can
|be quit in
|the middle by
|press on
|<esc> ix
sx initcouple
<i425>
ll:2000000000 perf1recact
ix
donecouple
isescpressed
or
se
ex lo.
<i426>
orinfo= pp
|action: ^roboapp info
|Info about pp
|this app ^ Interactive
ce pp
^orinfo: ^funcs include
pp pp
^g15 pmn fcm
<i427>
^vurobocam1 ^recact,pract
pp pp
^{or 2 or 3} ^ At least one
pp pp
&rrr {r.rest}& ^rrr to init
pp pp
^robotswing ^arrays, also
pp pp
<i428>
^robotswing to ^{q quits car}
pp pp
^init motors; ^recact keys:
pp pp
^source: ^i1 ^ recactinfo
pp pp
^ car
pp
<i429>
^{when setting ^ce screenclr
pp pp
^up fcm matrix ^qu quit
pp pp
^somecalc6 ^************
pp pp.
^is of help}
pp
<i430>
&orinfo&
zz
=======================================================FOOTNOTE #1:G15CONTROL installation instructions=======================================================
MsWindows works excellently with all general G15 PMN apps.
You can use G15ROBOT package at Windows to do robotics through
Windows, however that requires some tailor-made interactions
between robotic hardware and the G15 PMN. Linux Terminal is more
streamlined for rapid two-way interaction between a large
application and smaller auxillary programs called via it, and
so we have programmed the Open Robotics app initially for
use with Linux G15CONTROL package for G15 PMN. For good
robotwork, however, you must steer away from all ready-made
operating systems that tries to impose that unscientific,
untastely thing called "AI assistants" upon the workings
of the machine. We can tolerate it when we use a PC for
text processing--that in the background there hovers
pseudo-smart programs made under the false pretenses of
the phoney field of "AI"--but not when it comes to driving
a robot. It's too risky to have such codified dishonesty
in the machine then. We need (in every sense) CLEAN personal
computers to steer, and, indeed, be part of well-made robots.
When you have read through all the footnotes, the command
that should be entered on the PC {which, in a sense, becomes
an integral part of the robot--eventually mounted on the
robot itself, when we're talking a large-size robot doing
professional work} is this one:
./f3wx.sh
This presupposes that the contact between the PC and the
hardware has been adequately initialized {see the remaining
footnotes}, after the PC and the engines etc have been
switched on.
The ./f3wx.sh gives you a perfectly ordinary G15 PMN
but with the essential addition of also allowing various
commands at the Ubuntu linux command line to be performed
so as to let the G15 PMN program give exact instructions
to the robohardware and to fetch all its relevant input,
as has been registered by various input devices. This
requires setting up such as incam.sh {which prepares camera
images} suitable for the hardware you have.
These things you prepare through careful reading of all
the footnotes here, where you should have at least light
knowledge of the 'bash' Linux command line to begin with
When the G15 PMN program then refers to "a G15 PMN
environment like G15ROBOT" this will match it perfectly
{though other environments like this, not using Linux,
can be set up similarly, with hardly any change of the
G15 PMN program itself except some initial config lines}.SECURITY NOTICE: as stated elsewhere in these footnotes
also, unless you set it all up to work from a local user,
be sure to switch off the internet connection really well
when you keep on running via sudo -i, as root or
Administrator. However, internet connection can usually
be re-established by programs running as root, so you
should have a very 'clean' PC (eg, one that has hardly
been used at the net ) in case you like working as
Administrator. Whatever advices we give here--however much
they are given with the best of intents and, to our
knowledge, are well informed, you must accept full
responsibility for what you do with your PC and your
hardware, all the way through.
Because we consider it, at present, a good first-hand,
fairly inexpensive, fairly standard and also innocent way
of getting to begin, we advise the use of RobotShop's
AL5 kit with the SSC32U electronics. That can be a
starting-point that is, for the serious-minded robot
worker, from a meaningful "scratch": it can be gradually
built upon so as to make really useful larger robots
with many more features. After this, other types of
electronics and motors and substancies can be used
in making even better robots, where the same expertise
and much the same G15 PMN FCM programs are put to
ever-new uses. So the core starting-point G15 PMN
open robotics program is, in the form as presented
here with full source on this page, set up to work,
at first, with the SSC32U {ie, SSC32-U} card and
one of the well-known RobotShop AL5 kits {eg AL5D,
though a shorter roboarm can though give it more
strength}. This core G15 PMN OpenRobotics page links
to subpages of itself {see the section just on top
of the program} with simple or not-so-simple variations
of this starting-point not just to various robotasks,
but to other robohardware. The task-specific roboapps
we come with should always be further subject to
further entrainment by a robotech guy, for data
entrainment is the key to make a robot fit new
circumstances and variations in construction even
as the well-made G15 PMN roboapp itself may need
no or hardly any change. That is to say, the data
bases included with task-specific roboapps are
meant to be suitably overwritten by further acts
of entrainment in each local situation, by the
entrainment functions included with the app. In
addition to using these entrainment functions,
additional configurations and adjustments inside
the programs are usually necessary.
So, if you can, if you haven't already done so,
acquire and assemble an AL5 roboarm kit from
RobotShop.com
{Note that we have no commercial affiliation with them.}
While their kit can work on a MsWindows PC and RobotShop
has many worthwhile programs available, the way we do it
through G15 PMN robotics is to plug the hardware into the PC
and only run standard Ubuntu drivers and our G15CONTROL
G15 PMN package and that should suffice entirely.
Be sure also to get their very skillfully made card SSC32U
(which includes, as part of it, an excellently made standard
solution for doing RS232 via USB cables).
{While Arduino.cc products are interesting, it seems to
us, rightly or wrongly, that Arduino folks, in their design,
tend to wish to put the computing power into cards, ie, away
from PC's. We find that this this isn't ideal when going
into professional robotics work--unless we merely use the
Arduino chips to relay commands.
To do that, however, requires a bit of programming of
the chips and that we do not see that it is necessary to
do when SSC32U can drive the servos really well. However
there is no reason why you cannot start with an Arduino card
connected to servos if you are prepared to pre-program it
suitably to mimick the SSC32U commands as much as possible
and then make the adequate changes in the program here.}
Additional robohardware:
Connect three of light inexpensive cameras ("webcams")
to the computer also; one of them mounted on the roboarm--
how they are set up exactly depends on the context, on
the program, on the tasks to be done. With a camera that
is light enough, one should normally be attach one to
the roboelbow and it won't upset weight balancies any
too much. The other ones can be manually placed to fit
with the tasks to be done and when the robot is expanded
with more arms, they can contribute to adjusting these
camera positions. Take care to think through how stable it
all is--and that includes paying regular attention to how
well the wires that are part of the robot are kept protected,
also in the sense of they being shielded given varied use
of the robohardware in a range of circumstances. Give care
to regular maintainance of all your robots, just as for all
your cars, and, as Pirsig pointed out, apply gumption.
You must have a large PC keyboard for any serious dealing
with G15 PMN in any form. Connect this to the PC. Also get a
USB socket-multiplier, they're cheap, to handle more cables,
if you are using USB cables (which may be a better idea than
using wireless when it comes to professional robotics work,
where we want as much obviousness as possible as to just what
is connected to, and steering, what). The large keyboard must
have easily accessible F1 to F12, large PgDn, PgUp, Home, and
End keys, and so on. If you have to save in on cables, perhaps
you can use a laptop's mouse pad instead of a real mouse
pointer device. And do play around with G15 PMN for a while
before you dabble into this very advanced package. There are
numerous games, all with source, all easily modified, that
can give you a quick sense of upper hand with the ways,
means and concepts of G15 PMN; the use of CTR-W to activate
'menu mode' and right-click to re-activate the 'edit mode'
of the CAR editor or graphics platform from which to launch
the G15 PMN programs. A mini-course for a tech guy who is a
very rapid learner would include some days or weeks with themes
such as: how to read such as 'D2' and 'D8' in the code ('jump
this many function-only lines in case of..'), 'F1' ('get one
more than index i1'), 'BASIS' (an optimistic view of the
number zero), and 'DANCE' (the starting-point of much fun and a
very vivid way of saying the number one). It includes also
learning to use the CAR editor (how to insert free cards: to
copy CTR-C very many more cards than relevant eg 3333 followed
by lineshift, move some cards ahead by PgDn, and using CTR-T
puT them in, followed by Space}. The CAR editor displays the
program in its own type of G15 PMN made font, which is
speaking to the programmer far more than any other font
can do--making the program come across quite vividly. G15 PMN
is, unlike Forth, not a 'write only' language; the programs
remain readable through the CAR editor--forever. The days
of fast learning G15 PMN for the tech guy also includes
handling mounts and unmounts of programs, and understanding
that when eg the i-disk is 'mounted' to a program, then if
you save to the i-disk you save to the mounted program rather
than to the i-disk you have when no program is mounted. It
also involves getting your hands to learn all the relevant
key-clicks, from ALT-END and ALT-HOME inside B9edit {more
at the document g:69} to CTR-R and Tab inside CAR editor;
and it includes knowing a bit of the layout of the docs of
the Third Foundation overview over inbuilt G15 PMN
functions, as well as getting to know and love the SCAN
command, which, when entered in G15 PMN 3rd Foundation
terminal, and followed up by use of the commands CAR and
MMM, or for lineshift texts, also the commands LUSH and
MMMM, can retrieve any definition inside the Third
Foundation when applied to the disk {often F} that holds
all the source for G15 PMN. This involves seeking both
on the two-letter predefined {PD} words, eg, you can seek
up definition of "AW" by typing " AW:" into SCAN, or you
can seek up definition of three-and-more-letter functions
such as MAKEFIT by typing "MAKEFIT=" into SCAN. Start to
SCAN at F1 and type eg 3333 as quantity cards to seek all
the 3rd Foundation of the F-disk as included with the
Open Robotics app. And similarly for definitions in the
specific app you are at present working on, which perhaps
is at i-disk. Finally, the tech guy learns how to copy a
program so as to append the Third Foundation {with or
without extra PD's as extension of it}, so it starts
directly just with a mouse-click inside the CAR editor,
when speedy startups of programs are called for.
As for the advised initial robohardware please also note:
The AL5 roboarm in its original form can lift just slightly
more than pieces of paper (unless cleverly navigated and/or
mechanically hooked up with some other elements so as to distribute
the force in a certain manner suitable for some other tasks) and so
only a narrow range of practical tasks can be done with it. However,
and this is the important point: both the software we make for
it and the input devices you attach and the SSC32U card can
be used when you go beyond those servos to a more complex
robot having more ranges of movement and much more power,
also by far more powerful servos. As for servos, the lovely
SSC32U interacts with the industry standards for servos. In
these cases, however, one will have to provide separate power
supplies for the more powerful servos, and it requires a bit of
electronics competence to do this correctly. The principle is
the same for low-power battery driven robots and high-ampere
servo motors in robots using cables to an external power
supply; the present info may help (the source links given
are inside the image may or may not refer to further info
when you view this):
So, if you are careful, and look around for various servos,
you can start with the AL5 SSC32U concept and gradually build
robots that can do real practical stuff. The software that
works for simpler tasks should be fairly easy to adapt, given
that you work with the G15 PMN programming language regularly.
Here's how to get G15CONTROL up fast (and we recommend a really
well-supported up-to-date Linux because of the need for easy
access to a range of auxillary programs; and in the case of
Ubuntu, it probably means the main release of Ubuntu rather
than one of the "flavours"):
1. Get Ubuntu 64-bit Desktop from ubuntu.com
(probably one with long-term support lasting years ahead).
This is easily installed through a completely blank USB
stick using the Rufus program their tutorial points to,
to a number of typical laptops such as HP, Asus etc,
to which I always attach a USB keyboard and a USB mouse
and configure the keyboard to be set to U.S. English
as the first thing. {We do recommend the 32-bit approach
to computing, for reasons connected to the first-handedness
of the 32-bit numbers as spelled out many other places,
but the majority in the Linux community has gone down
the 64-bit drain and we have to live with that: the
32-bit Desktop isn't easily available anymore, and we
are wanting to use standards with a minimum of change.}
2. Once it is in place, install all updates, reboot.
3. Start up the Terminal program there.
4. Type the following, with net up, and give it time.
The point is to get useful auxillary programs and to
prepare the 64-bit Linux to run 32-bit programs as
effortlessly as can be (the --fix-missing are
probably unnecessary; "apt update" important to do
once in a while and every time after deep-cleansing a
Linux PC with such as Bleachbit):
sudo -i
apt update
apt update --fix-missing
apt install wine
apt update --fix-missing
apt install libsdl1.2-dev:i386
exit
exit
Watch out when you type in the command to install "Wine"
(which in some countries should not be done via a
graphical interface, only via a text interface, because
the graphics goes into a loop when it tries to load some
fonts, as it seems) that it will ask a question as to
whether you accept a licence. Press Tabulator {-->|} on
the keyboard until OK shows, then press Space to signal
the OK. Then press Arrow-right and Arrow-left until you
select YES, and press Space to signal the YES. During
the install of Wine it may loop quite a lot trying
to get some fontfiles from SourceForge.net but as long as
it gets on, after some minutes, it won't affect us; you
can cure any such font issue by looking at what we wrote
about "msttcorefonts" in our
yoga6d.org/economy.htm page.
{It's a thing that hasn't been fixed in the installation
procedures for this important package for years; so Wine will
probably be like this until 2050 or so.}
5. Unzip y6.zip from norskesites.org/fic3 to where you
want to run it from.
6. Rename this folder to g15control.
7. Get hold of g15control.zip from
norskesites.org/fic3/fic3inf3.htm
and unzip the content files INSIDE the folder you prepared
in point 5 and 6. The text versions here you run each
time you press search button in Yoga6d.org/look.htm.
8. Go into this folder via cd command in Terminal, being
the user you want to be, and type ./g15.sh and see that it
works (change the pixel size of the display inside if you
have a stiff videocard, according to the readme texts). Then
type ./f3wx.sh for the expanded version that gives the opportunity
of G15 PMN programs to call on extra programs via the Linux
terminal while the graphics G15 PMN fills the screen, or,
when you press DELETE button, a window.
The G15CONTROL package is for folks who know what they
do with their computers and who are properly security-
aware, and all the more so if they run the package as
administrators. The normal G15 PMN (wing15pmn.zip, y6.zip,
and y6all.zip) don't allow control over the Terminal and
so there's a extra layer of security in these cases.
=======================================================FOOTNOTE #2:ACCESSING USB/RS232 FROM UBUNTU LINUX AND SIMILAR=======================================================
The AL5 SSC32U roboarm (mentioned above) comes with a card
that has an inbuilt USB-RS232 converter. The first times you
start working with Linux relative to this card, you might
begin like this (don't plug the roboarm in yet).
CABLES TO AND FROM SENSITIVE EQUIPMENT OUGHT TO BE
OF HIGH QUALITY AND NOT OVERLY LONG. ANY USE OF A
MULTI-SOCKET, SUCH AS AN USB-MULTISOCKET TO ALLOW
SEVERAL CONNECTORS, SUCH AS FROM SEVERAL CAMERAS,
SHOULD BE DONE ONLY BY MEANS OF HIGH-QUALITY HIGH-
BANDWIDTH MULTI-SOCKETS, AND THE ACTUAL CABLE TO
THE MOST SENSITIVE ROBOT-CONTROLLING ELECTRONICS
OUGHT TO BE CONNECTED AS DIRECTLY AS POSSIBLE TO THE
PC, RATHER THAN THROUGH A MULTI-SOCKET {RATHER
CONNECT THE OTHER THINGS TO THE MULTI-SOCKET}.
This concerns the initialization of the robotic equipment
but also its stability when it has been put to practical
work.
ANOTHER TIP FOR STABILITY OF ROBOT OUTPUT
DEVICES: WHEN YOU ARE SETTING UP THE EQUIPMENT
FULLY--NOT JUST FOR TESTING PURPOSES--THEN SPREAD
OUT THE USE OF CHANNELS INASMUCH AS IT IS NECESSARY
TO TAKE AWAY NOISE COMING INTO ANY CHANNEL. FOR
INSTANCE, ON THE SSC32U CARD, UNPLUG SERVO TO
CHANNEL#2 AND PLUG IT INTO CHANNEL#18 {THERE ARE
31 ON THIS CARD}, IN CASE CHANNEL#2 HAS NOISE
ISSUES ON IT ON A PARTICULAR HARDWARE SET UP
WITH MANY CAMERAS AND MULTISOCKETS AND A SIMPLE
LAPTOP PC.
But in all cases take precautions really well when
you set up robotic equipment, especially when you are
working out new robotic tasks and/or new robotic
hardware or environments:
WHEN YOU SWITCH THE ROBOTIC EQUIPMENT ON, IN
CASE OF INITIAL JUMPY MOVEMENTS OF IT, ANYTHING
QUITE NEAR IT WHICH IS EITHER HARD {SO IT COULD
DAMAGE THE EQUIPMENT} OR SENSITIVE {SO IT ITSELF
COULD BE DAMANGED} OUGHT TO BE COVERED OR MOVED
AT SAFE DISTANCE.
How you put this safety precaution into practise
depends entirely on the status of the robotic
hardware development and on the exact features of
the environment and the objects near it. It goes
without saying that living beings have to have the
highest priority as for the protection of health.
THE SERVOS ON THE AL5 ROBOARM ARE TO BE PLUGGED INTO
THE SSC32U CARD IN THIS WAY TO MOST EFFORTLESSLY WORK FIT
WHAT'S ON THIS PAGE, BUT AS SOON AS THEY ARE TO BE USED
WITHIN A PARTICULAR G15 PMN FCM Roboapp THEN THAT ROBOAPP
WILL SPECIFY OTHER CHANNELS FOR THE SERVOS AND OTHER
OUTPUT DEVICES IN USE: #0 to rotation inside the circular
pillbox at the base of the robotarm. #1 to the servo on
top of the pillbox. #2 to the servo above it on the
roboelbow. #3 to the robohand-lifter. #4 to the
robogripper. Depending on the weight distribution, the
roboarm lengths, etc, etc, what constitutes a meaningful
and good-looking "rest position" of the robot you're
building vary. The configs included here, incl in the
first cards of the main G15 PMN FCM robotics program,
are meant to be varied according to your first-hand
experience and insight.
Start up Terminal and work in Administrator mode until you
have set up this communication to work with a local user.
If you already have command 'screen', skip the second line.
Type:
sudo -i
apt install screen
Turn on the roboarm and its electronics, wait some seconds,
then plug in the USB cable to the PC. If the card has leds,
they should give a certain signal when the cable is plugged in.
Type:
dir /dev/tty*
With likelihood, you'll see /dev/ttyUSB0 there when the cable
is plugged in and it will disappear when it is not there (ie,
when you repeat the "dir" command). (It may be another number
or another tty--if you use RS232 hardware directly, which is a
brilliant thing to do, it will of course not have the "USB"
text at all, rather you'll have to figure out which number
of the tty it is. However). Let's assume ttyUSB0 is right.
Type:
screen /dev/ttyUSB0
A
This is a good (but manual) way to initialize the connection.
The letter "A" has no meaning here: this is just about sending
something harmless through the cable. Any leds on the SSC32U
card should change to indicate that communication is up.
Quit the "screen" program by a click on CTR-A then backslash (\)
followed by 'y' to confirm exit. (Keyboard info: "man screen").
NORMAL ROBOTIC PRECAUTION: BEFORE SWITCHING ON ROBOTIC
EQUIPMENT, CHECK THE FULL PHYSICAL RANGE OF ALL ITS
MOVABLE PARTS AND REMOVE ANY SENSITIVE, DANGEROUS, AND/OR
EXPENSIVE OBJECTS IN THE ENVIRONMENT THAT IT MAY BUMP
INTO IN CASE OF JERKY FAST FREE MOVEMENTS.
In a text editor like gedit, put a line like this to a file
like start3.txt, supposing that the servos of the AL5 are
plugged into channels #0 to #4 of the SSC32U card. The commands
here are card-dependent, obviously (some other cards may have
variations of the following, but SSC32U is very easy to control
this way):
#0 P1500 #4 P1500 T1800
And in start5.txt, put something like this:
#0 P750 #4 P750 T1800
Then type
cat start3.txt > /dev/ttyUSB0
and the roboarm should respond. {Gedit automatically puts
in a lineshift at the end of a file, and that is exactly
as it should be in this case. If you wish to check whether
there's a lineshift there, type cat start3.txt and
if it shows cleanly on the screen, so that the Linux
prompt comes on the next line, then there is a lineshift
there.} If not, try it all over again, after repositioning
the roboarm slightly so it is in a 'home' position. It is
sometimes possible to init the card {so that the servos
"purr"} by a number of repetitions of this sort, including
gentle positioning of the roboarm. Keep coffee away as the
arm may suddenly swing fast.
When it works, type
cat start5.txt > /dev/ttyUSB0
And it should move to another position (can use other channels
than just #0 and #4 here, of course). This is a manual but
instructive way to make Linux greet your robot-to-come. You
can experiment with ways of initializing the robot properly
without any of these actions, directly inside G15 PMN. But
it may also be of value to appreciate that the larger and
more professional robot we're talking about producing, the
more clever thought and creativity has got to go into the
question of how to ensure that the robot physically go into
jerking movements and how to get it back into proper
easy-going rhythm if the hardware interface electronics,
for one reason or another, goes into a somewhat confusing
state in the middle of a task. One way is to have several
entirely independent and differently-made-up robot devices
inside a single robot so that, on the assumptions that
always some of them are okay, the parts that aren't okay
can be physically checked by the okay parts until a proper
reset has taken place. However it is done, it has got to
be done really well, and the more properly the more
dangerous tasks a robot is set to.
Eventually, you want to tune a command to do it in a way
that fits each robotic configuration the best. A good
starting-point is here--and it is repetitive on purpose,
because 'cold robohardware' (incl its electronics)
requires repetitions. It takes about 11 and a half second
to perform the following lengthy command, which is called
--and G15 PMN roboapps typically expects it to be present--
"deeprrr.sh". This one initializes 10 of the 31 channels
of the SSC32U card, but it can easily be modified to fit
more channels and also a range of other, similar forms of
electronics. So you copy and paste these lines into the
text editor at the Linux command line, and save it as
deeprrr.sh, after which you run the chmod 755 deeprrr.sh
command to make it acceptable as command.
NORMAL ROBOTIC PRECAUTION: BEFORE SWITCHING ON ROBOTIC
EQUIPMENT, CHECK THE FULL PHYSICAL RANGE OF ALL ITS
MOVABLE PARTS AND REMOVE ANY SENSITIVE, DANGEROUS, AND/OR
EXPENSIVE OBJECTS IN THE ENVIRONMENT THAT IT MAY BUMP
INTO IN CASE OF JERKY FAST FREE MOVEMENTS.
Before switching the roboarm and its electronics on, move
it manually to a fairly normal position. Switch it on, plug
it in, and try the
./deeprrr.sh
command. Inside finished G15 PMN roboapps, this may typically
corresponds the command "deeprrr", and in some cases it is
used for re-init of robot even while a robo-application is
being performed.
# This is deeprrr.sh which is an EXAMPLE of how to more
# deeply reset the electronics and robohardware over a
# period of some 11.5 seconds all in all. The SSC32U
# card, as for channels 0 to 10, are given init commands
# several times over and the robohardware is given some
# time to accomodate it, may be suitable during startup
# This, then, is an EXAMPLE and it must be modified
# intelligently to suit the particular total context
# start it by ./deeprrr.sh
# Depending on how deep reset the electronics and hardware
# requires, it may be of value to run it a couple of times
echo "#0 P1500 #1 P1500 #2 P1500 #3 P1500" > /dev/ttyUSB0
echo "#4 P1500 #5 P1500 #6 P1500 #7 P1500" > /dev/ttyUSB0
echo "#8 P1500 #9 P1500 #10 P1500" > /dev/ttyUSB0
sleep 0.3
echo "#0 P1500" > /dev/ttyUSB0
echo "#0 P1500" > /dev/ttyUSB0
echo "#0 P1500 T250" > /dev/ttyUSB0
sleep 0.3
echo "#1 P1500" > /dev/ttyUSB0
echo "#1 P1500" > /dev/ttyUSB0
echo "#1 P1500 T250" > /dev/ttyUSB0
sleep 0.3
echo "#2 P1500" > /dev/ttyUSB0
echo "#2 P1500" > /dev/ttyUSB0
echo "#2 P1500 T250" > /dev/ttyUSB0
sleep 0.3
echo "#3 P1500" > /dev/ttyUSB0
echo "#3 P1500" > /dev/ttyUSB0
echo "#3 P1500 T250" > /dev/ttyUSB0
sleep 0.3
echo "#4 P1500" > /dev/ttyUSB0
echo "#4 P1500" > /dev/ttyUSB0
echo "#4 P1500 T250" > /dev/ttyUSB0
sleep 0.3
echo "#5 P1500" > /dev/ttyUSB0
echo "#5 P1500" > /dev/ttyUSB0
echo "#5 P1500 T250" > /dev/ttyUSB0
sleep 0.3
echo "#6 P1500" > /dev/ttyUSB0
echo "#6 P1500" > /dev/ttyUSB0
echo "#6 P1500 T250" > /dev/ttyUSB0
sleep 0.3
echo "#7 P1500" > /dev/ttyUSB0
echo "#7 P1500" > /dev/ttyUSB0
echo "#7 P1500 T250" > /dev/ttyUSB0
sleep 0.3
echo "#8 P1500" > /dev/ttyUSB0
echo "#8 P1500" > /dev/ttyUSB0
echo "#8 P1500 T250" > /dev/ttyUSB0
sleep 0.3
echo "#9 P1500" > /dev/ttyUSB0
echo "#9 P1500" > /dev/ttyUSB0
echo "#9 P1500 T250" > /dev/ttyUSB0
sleep 0.3
echo "#10 P1500" > /dev/ttyUSB0
echo "#10 P1500" > /dev/ttyUSB0
echo "#10 P1500 T250" > /dev/ttyUSB0
sleep 0.3
echo "#0 P1500 #1 P1500 #2 P1500 #3 P1500" > /dev/ttyUSB0
echo "#4 P1500 #5 P1500 #6 P1500 #7 P1500" > /dev/ttyUSB0
echo "#8 P1500 #9 P1500 #10 P1500" > /dev/ttyUSB0
sleep 0.3
echo "#0 P1500 #1 P1500 #2 P1500 #3 P1500" > /dev/ttyUSB0
echo "#4 P1500 #5 P1500 #6 P1500 #7 P1500" > /dev/ttyUSB0
echo "#8 P1500 #9 P1500 #10 P1500" > /dev/ttyUSB0
sleep 0.3
echo "#0 P1500" > /dev/ttyUSB0
echo "#0 P1500" > /dev/ttyUSB0
echo "#0 P1500 T500" > /dev/ttyUSB0
sleep 0.5
echo "#1 P1500" > /dev/ttyUSB0
echo "#1 P1500" > /dev/ttyUSB0
echo "#1 P1500 T250" > /dev/ttyUSB0
sleep 0.3
echo "#2 P1500" > /dev/ttyUSB0
echo "#2 P1500" > /dev/ttyUSB0
echo "#2 P1500 T250" > /dev/ttyUSB0
sleep 0.3
echo "#3 P1500" > /dev/ttyUSB0
echo "#3 P1500" > /dev/ttyUSB0
echo "#3 P1500 T250" > /dev/ttyUSB0
sleep 0.3
echo "#4 P1500" > /dev/ttyUSB0
echo "#4 P1500" > /dev/ttyUSB0
echo "#4 P1500 T250" > /dev/ttyUSB0
sleep 0.3
echo "#5 P1500" > /dev/ttyUSB0
echo "#5 P1500" > /dev/ttyUSB0
echo "#5 P1500 T250" > /dev/ttyUSB0
sleep 0.3
echo "#6 P1500" > /dev/ttyUSB0
echo "#6 P1500" > /dev/ttyUSB0
echo "#6 P1500 T250" > /dev/ttyUSB0
sleep 0.3
echo "#7 P1500" > /dev/ttyUSB0
echo "#7 P1500" > /dev/ttyUSB0
echo "#7 P1500 T250" > /dev/ttyUSB0
sleep 0.3
echo "#8 P1500" > /dev/ttyUSB0
echo "#8 P1500" > /dev/ttyUSB0
echo "#8 P1500 T250" > /dev/ttyUSB0
sleep 0.3
echo "#9 P1500" > /dev/ttyUSB0
echo "#9 P1500" > /dev/ttyUSB0
echo "#9 P1500 T250" > /dev/ttyUSB0
sleep 0.3
echo "#10 P1500" > /dev/ttyUSB0
echo "#10 P1500" > /dev/ttyUSB0
echo "#10 P1500 T250" > /dev/ttyUSB0
sleep 0.3
echo "#0 P1500 #1 P1500 #2 P1500 #3 P1500" > /dev/ttyUSB0
echo "#4 P1500 #5 P1500 #6 P1500 #7 P1500" > /dev/ttyUSB0
echo "#8 P1500 #9 P1500 #10 P1500" > /dev/ttyUSB0
sleep 0.3
echo "#0 P1500 #4 P750 #8 P1500 T1000" > /dev/ttyUSB0
sleep 1.1
echo "#1 P1700 #5 P1500 #7 P1500 T1000" > /dev/ttyUSB0
sleep 1.1
echo "#3 P1750 #2 P1700 #9 P1500 #10 P1500 T1000" > /dev/ttyUSB0
sleep 1.1
This completes the deeprrr.sh command. However, you can
easily extend it to more channels. For instance, when a G15
PMN Roboapp wishes to use channel #18 instead of channel #2,
you may want to add to the deeprrr.sh command additional
reset instructions for more channels; however, it may turn
out that the best is to leave it as it is, rather than
over-expand it, because the app may be programmed to fit
with the original deeprrr and handles the fact that not
all channels above #0-#9 are fully initialized.
When do you unplug some channels? Answer: when there is
noisy movements of an uncontrollable kind seeping into the
channel for some reason; the reason may simply be that the
bandwidths aren't luxurious enough in the present electronics
that you are using and isn't cause for concern, when you
after all have many channels available.
Whatever way you have to start the connection in a safe and
good way between the PC and the robot, once this connection
is up, you can focus on the core programming challenge, namely
to have a program match on the input from the input devices
of the robot and generate suitable output command sequences.
Except for occasional re-initialization of the various parts
of the hardware, more manual control shouldn't be necessary
after you have started it properly up. Let G15 PMN do the rest.
HOWEVER YOU INITIALIZE THE CONNECTION BETWEEN THE PC AND
THE CARD(S) AND THE SERVOS, YOU MAY WANT--AT LEAST IN THE
BEGINNING--TO DO IT EACH TIME BEFORE YOU START THE G15 PMN
UP VIA THE APPROPRIATE COMMAND, SUCH AS ./f3wx.sh.
FOR PROFESSIONAL ROBOTS, THIS CAN OF COURSE TAKE PLACE
MORE AUTOMATICALLY, BUT IT'S PART OF THE WHOLENESS OF
THIS APPROACH THAT THERE SHOULD BE HUMAN MINDS AND
HUMAN HANDS CLOSELY OVERLOOKING ALL ROBOTS.
After a session lasting hours--or in any session where you
just check out the connections--get the robot to be in a
proper rest position, unplug the robocable, switch off
the robopower, and do a full physical reboot of the PC, leaving
it off for half a minute, to really reinit the hardware ports
and such.
AND SO ON, FOR MORE ROBO-OUTPUT DEVICES.
By analogy, several more servos and indeed also other
output devices, which are part of the robot can be set up
like this. Let's appreciate that whatever output we give
the robot--and whatever appearance--the honest and
ethical approach is that it's not about fooling humans
into thinking it is smart or alive; rather, it's a
machine that's hopefully practical and that should
be easy to recognise AS a machine. That is to say, the
first-hand approach to robotics is to rule out the
smooth and rounded and skin-like covering of the
artefact, and stick to the notion that the most
beautful robots are the most square ones, with
protuding nuts and bolts and what not.
HOW TO CLEANSE THE PORT, IF YOU RUN THE PROGRAM WITHOUT
HAVING THE ROBOHARDWARE PLUGGED IN:
If you run the program which attempts to write to
such as /dev/ttyUSB0 when /dev/ttyUSB0 doesn't exist,
it will simply make a file there. Delete this file
before you call such as 'screen' to activate the
port. That is, unplug the ttyUSB0 entirely and
type rm /dev/ttyUSB0
and plug the cable back in and you can access the
port as normal.
For additional reset, nothing beats reboot.
=======================================================FOOTNOTE #3:TAKING PHOTOS VIA CAMERAS AT LINUX COMMAND LINE=======================================================
It's a general rule or hint when we program G15 PMN and
engage relevant hardware for it that we don't try and
utilize every bit of the hardware--just as you don't
run a car's engine at needlessly low gear. The cameras
are normally configured to yield a very relaxed quantity
of pixels each. We rather have several of them. While
slightly more expensive, this also has the excellent
side-effect of not occupying the i/o lines to the computer
too much with any one of them. And we get a standard
approach in the program as to how these are to be handled,
we don't need a special program for any one of them.
FIRST, WE CONNECT THE FIRST CAMERA.
The program above expects you to provide it with a working
command named "incam.sh", which produces, from a robotic webcam,
the file "incam.bmp", a 500x500 bmp image of the particular
essential BMP type that G15 PMN easily converts into its own pet
image format, called GEM. Since this page is oriented towards
programmers with competence, and since there may be all sorts
of variations (many cameras; different pixel-ratio of them;
other input sources to be treated in similar ways), it is best
that you set it up yourself. The example here should work in
most cases where you put a plain Ubuntu 64-bit to a plain
laptop and buys the cheapest light webcam with USB cable any
decent electronics shop can offer you.
Open a terminal, work initially as administrator (hint: turn
the net connection off when you work with robotics on a PC
where you stick to 'root' user, except when you do particular
tasks such as loading in new programs or checking this or
that through a browser), then you can later set up a user that
has the appropriate rights to do suitable hardware i/o.
Type:
sudo -i
and type, as normal, the main password, so that you have
Administrator (root) rights. Check if you have the program
'streamer'. If not, type
apt install streamer
and get it in. Standard in Ubuntu and for many other linux'es
is to have the command 'convert' enabled (ie, the ImageMagick
package). This will also be useful. Next, let's find out
where the webcam is. First, don't plug it in. Type
dir /dev/video*
Then plug in the little camera, wait half a minute or more,
and repeat the command. Eg, you may find that /dev/video1 is
added and that /dev/video0 perhaps already were there, in
which case it may refer to an inbuilt camera. Then, let's
make the incam.sh--you may copy the lines from this page,
edit them if necessary, and paste them into gedit. If it
doesn't work at all, play around with the 'streamer'
command in isolation. (There are a handful of other programs
that can do the job but streamer is particularly neat.)
Next, cd into the "g15control" folder (as you set up in
footnote #1), and type:
gedit incam.sh
Inside the editor, paste some lines into it, where you edit
the /dev/video1 part in case you have another device for
the camera, and also edit the 640x480 part in case the
proportions of its standard photo size are different
(try removing the -s 640x480 part in case, and see what
the size of the incam3.pgm is with the program "eog",
where you type eog incam3.pgm and then press ALT-ENTER
to see the inbuilt proportions for this camera; calculate
better proportions, and put new numbers into relevant lines).
Here, then, are the lines you paste to gedit:
rm -f incam*.pgm
rm -f incam*.bmp
streamer -s 640x480 -c /dev/video1 -o incam3.pgm -q
sleep 0.1s
convert incam3.pgm -resize '640x640' incam5.pgm
convert -size 500x500 tile:incam5.pgm incam8.bmp
sleep 0.1s
./bmpgreenx3-64bit incam8.bmp incam.bmp > info.txt
sleep 0.1s
(The -64bit suffix is normally not necessary when
you have set up the 64-bit Linux to carry out 32-bit
work faithfully; program is inside the G15CONTROL zip.)
{The first of the 'convert' command is usually
superfluous but in some cases it may normalize the
image--'convert' is a bit picky--so that the overall
chance is that a more consistent total result is
gotten out of the second 'convert' call. In any case,
the first 'convert' does no harm and is one of the
lines in the script that performs fast.}
The "sleep" commands allow the file system to get a
grip on the file which enhances file integrities in
loops presumably going for hours and where we don't
want any pointless errors to arise by hasting things.
Save the little script by CTR-S and at command line
again type
chmod 755 incam.sh
to enable it as an acceptable command, and check it by
./incam.sh
eog incam.bmp
in which case a beautiful green camera photo should
show, perfectly square (in which a few lines on top or
bottom may be added by the 'screen' command as it tries
to access the camera through perhaps a bundle of other
USB-connections all competing for bandwidth--this is to
be expected, and the program will normally overlook
that which goes on in the edges anyway). Note: you may
find that it is easier to have consistently working
result images, if, for many cameras, you don't try to
squeeze the maximum viewrange out of them.
As an extra control, type
dir -l incam.bmp
and it should tell that the .bmp file has size 251078.
This is what in G15 PMN jargon is a 'pure' BMP format.
{A program like Gimp can produce it when using an
indexed 256 color palette, when, during export, the
socalled 'Extra options' is selected and in that,
the option 'No color space info' is selected.}
The G15 PMN robotics program can then call on your
command "./incam.sh" whenever it "pleases", so as to
produce a perfectly readable snapshot of what is in
front of the camera as monochrome green image incam.bmp,
all taking place in the same folder as has the normal
.g15 files, and where you start the G15 PMN program
through the ./f3wx.sh command.
SECOND, WE CONNECT THE SECOND CAMERA.
The extra cameras provides a different view of what
is going on. For one thing, this makes it much
more easy for the program to figure out what's
going on--as it will have more of a bird's eye
perspective of the activity of the robohand.
You may have to acquire a multiple socket USB
connector--again, an inexpensive standard
device in any well-equipped electronics store--
to have enough USB connectors to the PC.
In software, this is set up entirely like you set
up number 1, only with a phrase like /dev/video2
in case the first camera had /dev/video1. Type
gedit in2cam.sh
Here, then, are the lines you paste and possibly edit,
into gedit (and remember to do the chmod with it):
rm -f in2cam*.pgm
rm -f in2cam*.bmp
streamer -s 640x480 -c /dev/video2 -o in2cam3.pgm -q
sleep 0.1s
convert in2cam3.pgm -resize '640x640' in2cam5.pgm
convert -size 500x500 tile:in2cam5.pgm in2cam8.bmp
sleep 0.1s
./bmpgreenx3-64bit in2cam8.bmp in2cam.bmp > info2.txt
sleep 0.1s
THIRD, WE CONNECT THE THIRD CAMERA.
rm -f in3cam*.pgm
rm -f in3cam*.bmp
streamer -s 640x480 -c /dev/video3 -o in3cam3.pgm -q
sleep 0.1s
convert in3cam3.pgm -resize '640x640' in3cam5.pgm
convert -size 500x500 tile:in3cam5.pgm in3cam8.bmp
sleep 0.1s
./bmpgreenx3-64bit in3cam8.bmp in3cam.bmp > info3.txt
sleep 0.1s
AND SO ON, FOR MORE ROBOINPUT DEVICES.
By analogy, several more cameras and indeed also other input
devices, which are part of the robot, can be set up like this.
=======================================================FOOTNOTE #4:WHY NO GENERAL INTELLIGENCE ALGORITHM IS POSSIBLE=======================================================
IS A GENERAL INTELLIGENCE ALGORITHM POSSIBLE? SCIENTIFICALLY, NO.
AND THAT'S PROVEN.
The best brains--literally--in the 20th century had a gigantic
intellectual clash over just this theme, and, as one of the
accidents of this war, computers came into being. But the
computer didn't come into being because it was considered
interesting as a machine, but rather because it was considered
a useful conceptual idea as a logical tool in the war against
intuition, where Alan Turing were the leading general on one
side, and the articles by Kurt Goedel on incompleteness from
the earliest years of 1930 were the chief military force on
the other side. As many has pointed out, both before and after
Oxford mathematician Roger Penrose's giant popular and
much-discussed work entitled, "The Emperor's New Mind", the
more Turing tried to disprove Goedel's incompleteness, the
more devastating did the incompleteness become. Eventually,
the result that was established was (put very simply) the
following:
it requires a non-mechanical creative type of intuitive
perception--one that cannot in principle be made into an
algorithm--to make a proper system that summarizes the
behaviour of a system in a context.
Put more simply, we must keep on inventing how to solve it,
--the one thing that cannot be solved once and forever is
how to solve it.
This either means that human brains aren't intelligent or that
they aren't machines. If they aren't machines, what are they?
They may be, as the brain researcher (and collaborator with
Penrose) Stuart Hameroff has indicated, 'quantum orchestras'.
Not something that one can imitate in the laboratory, but rather
an extremely finetuned coherence flux which has sensitivities
to something involving a perception that cannot be reduced
merely to the interplay between atoms and forces. What about
socalled 'quantum computers'? First of all, every PC is a
quantum computer because silicon semiconductors are quantum
objects, but they are totally mechanical because that's the
way they are constructed. Second of all, no human laboratory
has ever really harnessed more subtle quantum features in the
way wishful anti-intuition researchers like David Deutsch
have been speculating on for decades--though billions of
dollars have been poured into the projects. The claims of
some big companies that they have got some 'quantum bits'
are to be regarded as an attempt to justify to their
shareholders that they haven't misspent money whereas in
fact they have misspent money. THERE IS NO QUANTUM COMPUTER
NOR WILL THERE EVER BE, except in the sense that quantum
physics maps the structure of some of the surface of the
material world including our personal computers {for a
more precise treatment of this theme, cfr the super-model
theory by this author, in which some papers are included
with the Third Foundation package for G15 PMN listed on the
G15 PMN app page}.
At the present era, it isn't into cheap fashion to speak of the
brain as something nonmechanical, because one is taken to be
some kind of crazy anti-scientist type. But hard science
speaks against the present hype around mechanisation of
intelligence and society--the really hard science, that is,
not the wishful thinking about science that is easily relayed
by radio, TV, and on the net, and by bosses of AI-greedy
companies, and by the sponsored research positions they have
established in pro-mechanist universities like Stanford and
in private research laboratories. All this, however, concerns
a battle that has been decided a long time ago, and not to
the favour of those who believe in AI.
Does this has practical consequences for us as robot
programmers? Enormously. And one of the things is that you
mustn't try to codify the core perception or perception-action
module once and for all. Rather, it must be adapted to each
context. And if there is one thing that is hated by the
pro-AI league in this world, it is contexts. But that's
how it goes: we must always have human programmers with
real minds because each new task to be done in this world,
in each new context, requires fresh programming. That's
Goedel's second incompleteness theorem, and related works
around that and in prolongation also of philosophical
reflections on infinite sets and such, put into digital
practise for daily life programmers.
To be still more concrete, it means that we need not AI,
but rather something like FCM--first-hand computerised
mentality--which is, in each robotic program, an
expression of the creative intuitive perception of the
programmer, and his or her feelings about the matter--
and with no final codification of how this is done.
That is to say, FCM must be set up creatively for each
program.
Let us bring in a slightly related but also very
different and more mundane theme, at the completion
of this footnote: The entrainment of data. We don't say
teach or learn when it comes to our contact with robots,
rather "entrainment" can do. This entrainment will
often have to be done anew to each local
environment and with each slight variation of the
particular robotic hardware. The databases of
entrainment that you get with each G15 PMN robotics
app branch are therefore (usually) only meant to be
examples as how you can begin to entrain. The G15 PMN
FCM open robotics app comes with inbuilt functions
where entrainment of robotic moves and building of
matching patterns (not 'recognition', for that is
a psychological word) can be erected, with fair ease,
by the robotic programmer. The real, live, human
programmer with a human head and heart.
=======================================================FOOTNOTE #5:THE BEST INTERACTION TYPES BETWEEN HUMAN AND ROBOT,AND WHY NATURAL LANGUAGE PROGRAMS HAVE NO ROLE IN IT=======================================================
The only point about robots lies in how useful they are to
human beings. This usefulness requires a meaningful type of
interaction between humans and robots. This interaction, or
"communication", must be designed by those who work out the
robohardware and robosoftware.
A key point about good communication is not operating under
false pretenses. A program is an expression of the
programmer(s) mentality. Similarly, hardware is an expression
of the mentality of the hardware designers. If the makers have
an honest intention, and if these programmers and designers
are well-informed about the variety of human minds who may
interact with the programs and the hardware, we can get
good communication.
Human natural language interaction programs is chiefly
about a program having been made so as to impress or so as to
do a preprogrammed task within a set of extremely narrowly
defined actions given the pattern matching over a keyword that
appears in the flow of talk from the human. This fits some
premature scifi books, but it is so inaccurate, unless the
hardware is unfit for doing more than rediculously few tasks,
that little or no professional work can be done this way,
and certainly not if we have any grasp what was pointed out
in the foregoing footnote, ie, that computers have no minds,
and that algorithms cannot possibly have intelligence, no
matter how cleverly they are put together. A natural language
like English suffers tremendously when algorithms hack in on
it. The artificiality gets extreme and is disgusting for any
educated human of taste. English, in addition, has in it a
the natural type of context-independence that is the
characteristics of any real mind: and so, by definition,
a computer program--which can never escape its own context--
doing such as English is doing something that involves
dishonesty. This dishonesty creeps into all the work unless
rooted out in the beginning. Cheaply thought-out companies
may try and put away human language operators in favour of
algorithms dealing with human language, and some of them
may even earn money: but so may a number of other unworthy
enterprises in society.
A robot should by design look mechanical and the interface
between it and human beings should have an honest mechanical
feel to it. The tasks the robot are, at any time, set up to
do should not be put inside a cloud of words, but rather, in
one way or another, be as obvious as the on-off button on a
desktop lamp. The need for a human being to steer, change,
and stop a robot requires the type of thinking that goes
into design processes of ANY mechanical product. It can be
informed by the interactivity that a human being may have
in relation to an animal--and aptly so. Robots, at best, are
useful animals. Immense creativity is required by the human
robot makers to find out what types of communication that
are called for in each case--and the energy should not be
wasted into silly language games, made to impress and
confuse. Human beings are immensely good at communicating
with a very wide range of self-powered objects, natural or
man-made, that in no way try to mimick human beings. The very
act of imitation of human beings, whether in looks or in
language behaviour, is a token of the type of approach
that no philosophically inclined humans would ever partake
in. Communication without human-imitation is where the
lucky focus must be directed, by the robot-makers.
=======================================================FOOTNOTE #6:PROTECTION OF HEALTH, ETHICS AND HARDWARE=======================================================
The responsibility -- to yourself, to other people, to the hardware,
to the environment, to the house/office/studio/flat etc -- as for
any effects created by following these advices if FULLY YOUR OWN.
There is no guarantee that following the advices on this page
is adequate in this regard.
Health: your own health, and the health of any people and living
beings around you, is a concern that is proportional to the power
of the robot. Put correspondingly more foresightfulness into it
as it gets more power (of whatever kind).
Ethics: define the domain that you wish a robot to work within,
and define the ethical norms that should apply within that domain,
and work to make what you do fit those norms--also within the
steering programs. Also, put in mechanisms in the program for
matching on when it has crossed the borders of that domain into
another; and put in mechanisms for allowing people around you
to switch off any robot gone astray.
Hardware: microelectronics, cable and so on are brittle but any
program experimentation work with a robot involves engines
putting perhaps also heavy roboarms and so on at unexpected
places--and all such considerations are greater, the more
advanced and powerful the robot. It follows that you must give
a robot a wide berth when working with it--and wider, the
further you have come with giving it capabilities. But it may
also be that a program somehow leads to a wrecking of the
hardware. That is something you must calculate into the whole
assessment of the situation--and it is ALL YOUR OWN RESPONSIBILITY
when you use free and open tools like on this page.
And never, ever claim that the machinery is intelligent:
algorithms are worse than stupid, they aren't even competing
in the area of intelligence, for there isn't the first flicker
of a sliver of a fraction of mind in them, no matter what the
CEO of this and that bogus big company says. {Cfr notes, many
places on the net, also from this writer's hand, on how
developments after Goedel's incompleteness theorem and
in biology after quantum physics contribute to indicating
that consciousness cannot be considered to be properly
analyzed from the viewpoint of an algorithmic paradigm.}
So it is inevitable that the insightful, philosophically
aware programmer doesn't contribute to making machines
that lie about themselves--whether in looks or in
behaviour--such as by conveying the false impression
that a human artefact is on level with live minds.
Whenever a psychological word refers to a machine, a
program, an algorithm, or a human artefact in general,
it must, at least, get quotes around itself. A machine
doesn't think: it "thinks". Other ways of doing it are
unscientific and cheap--never mind what some professors
may tell you.
Part of ethics is also to ask yourself: what types of jobs
should be reserved for humans {ie, robots should only do
hopelessly boring tasks, in the ethical perspective of what
types of society development we wish to contribute to}.
Good ethics implies good synchronicities. Take care!
It's supposed to be meaningful, fun and also practical, but
all this involves a great responsibility to think in much
wider and deeper perspectives than the technical.
Enough talk. Just apply your mind--and your intuition.
=======================================================
About SRW, Stein R. Weber, alias Henning Bråten, author of this page:
The author, who, despite being called 'the professor' at
school, and who, despite four years of running a student
and science oriented Norwegian magazine which had in-depth
academic interviews with physicists and thinkers including
(at his hotel in London) Ilya Prigogine, (in Oxford)
Roger Penrose, (in Paris) Francisco Varela, (in Oslo,
Bergen, Hardangervidda and California) Arne Naess
and (at Bohr Institute, Copenhagen) Holger-Bech Nielsen,
never bothered to finish University but rather decided
that the thing to do in life is to apply the personal
artist's touch about everything and ignore the mainstream
inasmuch as it ignores him. The most formative experiences
of his involved his decision to make a bundle of intuition
and logic during a period of some one to two years in
New York, which also saw him through some rediculous
work for the United Nations. This optimistic attitude has
taken him into fields including programming language
making, fashion photography, currency trading and ballerina
painting, having a passionate interest in beauty whether
abstract as in robotics design and physics and philosophy
and mysticism or concrete as in young human female beauty,
whether impressionistic as in painting or ultra-concrete as
in nude photography. The latter is a fountain of energy
that he pours into the more abstract works and G15 PMN is
a sort of summary of all this, made also in the hope that
at some time there will be students to this approach
(in what he optimistically calls "G15 Intraplates
Multiversity", a non-uni-versity approach to the art
of thinking). His names have diversified since he started
out, for the fun of it, not to hide anything. They are
all summarized here (where you also find contact info):
norskesites.org/steinweber/english/=======================================================