Commit 25547096 authored by Jake Read's avatar Jake Read

add soma

parent 37bea394
// 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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment