Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Jake Read
rndmc
Commits
25547096
Commit
25547096
authored
Dec 09, 2018
by
Jake Read
Browse files
add soma
parent
37bea394
Changes
4
Hide whitespace changes
Inline
Side-by-side
modules/robot/forwardTransform.js
0 → 100644
View file @
25547096
// boilerplate atkapi header
const
JSUnit
=
require
(
'
../../src/jsunit.js
'
)
const
MJS
=
require
(
'
mathjs
'
)
let
Input
=
JSUnit
.
Input
let
Output
=
JSUnit
.
Output
let
State
=
JSUnit
.
State
function
forwardTransform
()
{
var
theta1
=
0
var
theta2
=
0
var
l1
=
0
var
l2
=
0
var
forwardTransform
=
{
description
:
{
name
:
'
forwardTransform Parser
'
,
alt
:
'
line of forwardTransform -> points
'
}
}
// log more
var
verbose
=
false
// one caveat here is that we can't dynamically add objects to this,
// or they don't get getter / settered when we do
forwardTransform
.
state
=
State
()
// forwardTransform.state.mode = 'G0'
// forwardTransform.state.G0 = 1200
// forwardTransform.state.G1 = 400
forwardTransform
.
inputs
=
{
theta1
:
Input
(
'
any
'
,
intakeTheta1
),
theta2
:
Input
(
'
any
'
,
intakeTheta2
),
l1
:
Input
(
'
any
'
,
intakeL1
),
l2
:
Input
(
'
any
'
,
intakeL2
)
}
forwardTransform
.
outputs
=
{
originpt
:
Output
(
'
tuple?
'
),
jointpt
:
Output
(
'
tuple?
'
),
touchpt
:
Output
(
'
tuple?
'
)
// instructionOut: Output('move instruction'),
// modeChange: Output('string')
}
function
intakeTheta1
(
num
){
theta1
=
num
var
points
=
parseforwardTransform
()
forwardTransform
.
outputs
.
originpt
.
emit
(
points
.
originpt
)
forwardTransform
.
outputs
.
jointpt
.
emit
(
points
.
jointpt
)
forwardTransform
.
outputs
.
touchpt
.
emit
(
points
.
touchpt
)
}
function
intakeTheta2
(
num
){
theta2
=
num
var
points
=
parseforwardTransform
()
forwardTransform
.
outputs
.
originpt
.
emit
(
points
.
originpt
)
forwardTransform
.
outputs
.
jointpt
.
emit
(
points
.
jointpt
)
forwardTransform
.
outputs
.
touchpt
.
emit
(
points
.
touchpt
)
//console.log('theta2 input')
}
function
intakeL1
(
num
){
l1
=
num
var
points
=
parseforwardTransform
()
forwardTransform
.
outputs
.
originpt
.
emit
(
points
.
originpt
)
forwardTransform
.
outputs
.
jointpt
.
emit
(
points
.
jointpt
)
forwardTransform
.
outputs
.
touchpt
.
emit
(
points
.
touchpt
)
//console.log('l1 input')
}
function
intakeL2
(
num
){
l2
=
num
var
points
=
parseforwardTransform
()
forwardTransform
.
outputs
.
originpt
.
emit
(
points
.
originpt
)
forwardTransform
.
outputs
.
jointpt
.
emit
(
points
.
jointpt
)
forwardTransform
.
outputs
.
touchpt
.
emit
(
points
.
touchpt
)
//console.log('l2 input')
}
// input functions
/*
function onLineIn(str){
var instruction = parseforwardTransform(str)
if (instruction.hasMove) {
if(verbose) console.log('forwardTransform:', instruction)
forwardTransform.outputs.instructionOut.emit(instruction)
} else {
if(verbose) console.log('forwardTransform:', forwardTransform.state.mode)
forwardTransform.outputs.modeChange.emit(forwardTransform.state.mode)
}
}
*/
/*
// local functions
function getKeyValues(str) {
var kv = {}
for (var i = 0; i < str.length; i++) {
if (str[i].match('[A-Za-z]')) { // regex to match upper case letters
var lastIndex = str.indexOf(' ', i)
if (lastIndex < 0) {
lastIndex = str.length
}
var key = str[i].toUpperCase()
kv[key] = parseFloat(str.slice(i + 1, lastIndex))
}
}
return kv
}
*/
// TODO: test, can we link global vars to ui objects ...
// forwardTransform.ui.mode.value = var ? no bc set / get etc
// more like var = forwardTransform.ui.mode.value ? is this referential?
function
parseforwardTransform
()
{
var
points
=
{
originpt
:
(
0
,
0
),
jointpt
:
(
0
,
0
),
touchpt
:
(
0
,
0
)
}
points
.
jointpt
=
(
l1
*
Math
.
cos
(
theta1
),
l1
*
Math
.
sin
(
theta1
))
points
.
touchpt
=
(
l1
*
Math
.
cos
(
theta1
)
+
l2
*
Math
.
cos
(
theta2
),
l1
*
Math
.
sin
(
theta1
)
+
l2
*
Math
.
sin
(
theta2
))
/* var instruction = {
position: {},
hasMove: false,
speed: 0
}
kv = getKeyValues(str)
// track modality
if (kv.G == 0 | kv.G == 1) {
forwardTransform.state.mode = 'G' + kv.G.toString()
} else if (kv.G != null) {
// no arcs pls
console.log('unfriendly forwardTransform mode!', kv)
}
for (key in kv) {
if (key.match('[A-EX-Z]')) {
instruction.position[key] = kv[key]
instruction.hasMove = true
} else if (key.match('[F]')) {
// tricky / ugly: sets using the mode state string as object key
forwardTransform.state[forwardTransform.state.mode] = kv.F
}
}
instruction.speed = forwardTransform.state[forwardTransform.state.mode]
// and this for help later?
instruction.kv = kv
*/
return
points
}
return
forwardTransform
}
// export the module
module
.
exports
=
forwardTransform
\ No newline at end of file
modules/robot/leastSquares.js
0 → 100644
View file @
25547096
/* Easiest way I know of is to use "child_process" package which comes packaged with node.
Then you can do something like: */
const
JSUnit
=
require
(
'
../../src/jsunit.js
'
)
const
MJS
=
require
(
'
mathjs
'
)
const
spawn
=
require
(
"
child_process
"
).
spawn
//const express = require('express')
//const app = express()
let
Input
=
JSUnit
.
Input
let
Output
=
JSUnit
.
Output
let
State
=
JSUnit
.
State
function
leastSquares
()
{
var
theta1s
=
0
var
theta2s
=
0
var
leastSquares
=
{
description
:
{
name
:
'
leastSquares Parser
'
,
alt
:
'
line of leastSquares -> l1 and l2 values
'
}
}
// log more
// var verbose = false
// one caveat here is that we can't dynamically add objects to this,
// or they don't get getter / settered when we do
leastSquares
.
state
=
State
()
leastSquares
.
state
.
c
=
1
leastSquares
.
state
.
d
=
-
2
// leastSquares.state.G1 = 400
leastSquares
.
inputs
=
{
theta1s
:
Input
(
'
any
'
,
intakeTheta1s
),
// can be taken in as a string
theta2s
:
Input
(
'
any
'
,
intakeTheta2s
)
}
leastSquares
.
outputs
=
{
l1
:
Output
(
'
num
'
),
l2
:
Output
(
'
num
'
)
// instructionOut: Output('move instruction'),
// modeChange: Output('string')
}
function
intakeTheta1s
(
list
){
theta1s
=
list
var
lengths
=
parseleastSquares
()
}
function
intakeTheta2s
(
list
){
theta2s
=
list
var
lengths
=
parseleastSquares
()
//console.log('theta2 input')
}
function
thetasToStrings
(
list
){
}
function
parseleastSquares
()
{
var
lengths
=
{
//l1: 0,
//l2: 0
test
:
'
something
'
}
theta1sString
=
theta1s
.
toString
()
theta2sString
=
theta2s
.
toString
()
cString
=
leastSquares
.
state
.
c
.
toString
()
dString
=
leastSquares
.
state
.
d
.
toString
()
//console.log("we here at least:"+theta1sString)
const
pythonProcess
=
spawn
(
'
python
'
,[
'
py/leastSquares.py
'
,
theta1sString
,
theta2sString
,
cString
,
dString
])
//console.log('do we get here?')
//console.log(pythonProcess)
pythonProcess
.
stdout
.
on
(
'
data
'
,
(
data
)
=>
{
console
.
log
(
'
got here yay python!!
'
)
console
.
log
(
data
.
toString
())
lengths
.
test
=
data
.
toString
()
leastSquares
.
outputs
.
l1
.
emit
(
lengths
.
test
)
leastSquares
.
outputs
.
l2
.
emit
(
lengths
.
test
)
})
pythonProcess
.
stderr
.
on
(
'
data
'
,
function
(
data
){
console
.
log
(
"
Error:
"
+
data
);
});
/*
app.get('/', (req, res) => {
const { spawn } = require('child_process');
const pythonProcess = spawn('python',['leastSquares.py', theta1s, theta2s, c, d]);
pythonProcess.stdout.on('data', function(data) {
console.log(data.toString());
res.write(data);
res.end('end');
});
})
app.listen(4000, () => console.log('Application listening on port 4000!'))
*/
/* var instruction = {
position: {},
hasMove: false,
speed: 0
}
kv = getKeyValues(str)
// track modality
if (kv.G == 0 | kv.G == 1) {
leastSquares.state.mode = 'G' + kv.G.toString()
} else if (kv.G != null) {
// no arcs pls
console.log('unfriendly leastSquares mode!', kv)
}
for (key in kv) {
if (key.match('[A-EX-Z]')) {
instruction.position[key] = kv[key]
instruction.hasMove = true
} else if (key.match('[F]')) {
// tricky / ugly: sets using the mode state string as object key
leastSquares.state[leastSquares.state.mode] = kv.F
}
}
instruction.speed = leastSquares.state[leastSquares.state.mode]
// and this for help later?
instruction.kv = kv
*/
return
lengths
}
return
leastSquares
}
// export the module
module
.
exports
=
leastSquares
\ No newline at end of file
modules/ui/string.js
0 → 100644
View file @
25547096
// boilerplate rndmc header
const
JSUnit
=
require
(
'
../../src/jsunit.js
'
)
let
Input
=
JSUnit
.
Input
let
Output
=
JSUnit
.
Output
let
State
=
JSUnit
.
State
// interface elements
const
JSUI
=
require
(
'
../../src/jsui.js
'
)
let
UI
=
JSUI
.
UI
// a constructor, a fn, a javascript mess
function
uiString
()
{
// this is the tiny program-as-and-object that we'll load into rundmc
// description / name is required to load successfully
var
uistring
=
{
description
:
{
name
:
'
string-output
'
,
alt
:
'
for clicking
'
}
}
// the State() object is what the system scrapes for ui variables / updates from the UI
// this includes things like Button('title', callback), which are unique state variables
// they can also be found in jsunit.js
uistring
.
state
=
State
()
// alias !
var
state
=
uistring
.
state
state
.
string
=
'
something
'
uistring
.
ui
=
UI
()
var
ui
=
uistring
.
ui
ui
.
addElement
(
'
onNumberButton
'
,
'
./ui/uiButton.js
'
,
onStringDesire
)
ui
.
onNumberButton
.
onload
=
function
()
{
ui
.
onNumberButton
.
setText
(
'
number out ->
'
)
}
// inputs are required, and must be Input('type', callback)
uistring
.
inputs
=
{
thru
:
Input
(
'
any
'
,
onThruInput
),
// makes anything into string event
evt
:
Input
(
'
any
'
,
onStringDesire
)
}
// outputs: Output('type')
uistring
.
outputs
=
{
out
:
Output
(
'
string
'
)
}
// here's our input callback, specified in the input constructor
function
onThruInput
(
input
){
if
(
typeof
input
==
'
string
'
){
state
.
string
=
input
}
else
{
state
.
string
=
input
.
toString
()
}
onStringDesire
()
}
function
onStringDesire
(){
// here's how we fire an output.
uistring
.
outputs
.
out
.
emit
(
state
.
string
)
}
// gotta give the program this thing we made
return
uistring
}
// this for node.js's require() function
module
.
exports
=
uiString
\ No newline at end of file
py/leastSquares.py
0 → 100644
View file @
25547096
import
sys
import
math
as
m
import
numpy
as
np
#from mpl_toolkits.mplot3d import Axes3D
#import matplotlib.pyplot as plt
#import scipy.optimize
#import functools
#theta1s=[]
#theta2s=[]
#NOT USED IN CURRENT METHODOLOGY
# use all the time
def
calcx
(
l1
,
l2
,
theta1
,
theta2
):
return
(
l1
*
m
.
cos
(
theta1
)
+
l2
*
m
.
cos
(
theta2
))
#NOT USED IN CURRENT METHODOLOGY
# use to calculate touch probe stuff?
def
calcy
(
l1
,
l2
,
theta1
,
theta2
):
return
(
l1
*
m
.
sin
(
theta1
)
+
l2
*
m
.
sin
(
theta2
))
#NOT USED IN CURRENT METHODOLOGY
#in params, slope is first term (c) and y intercept is second term (d)
def
complicatedline
(
l1
,
l2
,
theta1
,
theta2
,
params
):
c
=
params
[
0
]
d
=
params
[
1
]
y
=
c
*
(
calcx
(
l1
,
l2
,
theta1
,
theta2
))
+
d
return
y
# SWITCHED STRATEGIES, now we are given C and D
#constructs matrix A for solving least squares
def
constructmatA
(
C
,
theta1s
,
theta2s
):
cfloat
=
float
(
C
)
a
=
[]
for
i
in
range
(
len
(
theta1s
)):
#print theta1s[i]
theta1
=
float
(
theta1s
[
i
])
theta2
=
float
(
theta2s
[
i
])
a
.
append
([
cfloat
*
m
.
cos
(
theta1
)
-
m
.
sin
(
theta1
),
cfloat
*
m
.
cos
(
theta2
)
-
m
.
sin
(
theta2
)])
return
a
def
constructmatb
(
D
,
theta1s
):
dfloat
=
float
(
D
)
b
=
[]
for
theta
in
theta1s
:
b
.
append
([
-
dfloat
])
return
b
theta1sString
=
sys
.
argv
[
1
]
theta2sString
=
sys
.
argv
[
2
]
cString
=
sys
.
argv
[
3
]
dString
=
sys
.
argv
[
4
]
theta1s
=
theta1sString
.
split
(
','
)
theta2s
=
theta2sString
.
split
(
','
)
c
=
int
(
cString
)
d
=
int
(
dString
)
A
=
constructmatA
(
c
,
theta1s
,
theta2s
)
b
=
constructmatb
(
d
,
theta1s
)
fullRes
=
np
.
linalg
.
lstsq
(
A
,
b
)
lengths
=
[
fullRes
[
0
][
0
][
0
],
fullRes
[
0
][
1
][
0
]]
print
lengths
sys
.
stdout
.
flush
()
'''
#test case
#theta1s=[m.pi/2, m.pi*50/180, m.pi*25/180]
#theta2s=[0, m.pi*10/180, m.pi*60/180]
theta1s=[m.pi*75/180, m.pi*60/180, m.pi*45/180]
theta2s=[m.pi*-30/180, m.pi*5/180, m.pi*15/180]
#test case with c = 0, d = 0 so x = 0 I DO NOT RECOMMEND USING C = 0 AND D = 0, i think information is lost this way
#current test case: c = 1, d = -2
testA = constructmatA(1, theta1s, theta2s)
testb = constructmatb(-2, theta1s)
np.linalg.lstsq(testA, testb)
'''
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment