Skip to content
Snippets Groups Projects
Commit 25547096 authored by Jake Read's avatar Jake Read
Browse files

add soma

parent 37bea394
Branches
No related tags found
No related merge requests found
// 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
/* 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
// 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
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
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment