Published
Edited
May 15, 2022
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
{
const [motor0, motor1, motor2, target] = nodes;
const dom = html`
<svg class="main-chart" viewBox="0 0 400 200">
<g>
<line id="line0" x1="${motor0.fx}" y1="${motor0.fy}" x2="${motor1.fx}" y2="${motor1.fy}" style="stroke:rgb(255,0,0, 0.4);stroke-width:2" />
<line id="line1" x1="${motor1.fx}" y1="${motor1.fy}" x2="${motor2.fx}" y2="${motor2.fy}" style="stroke:rgb(255,0,0, 0.4);stroke-width:2" />
<circle
id="motor0"
r="${motor0.r}"
cx="${motor0.x}"
cy="${motor0.y}"
fill="rgba(255, 0, 0, 0.7)"
/>
<circle
id="motor1"
r="${motor1.r}"
cx="${motor1.x}"
cy="${motor1.y}"
fill="rgba(0, 255, 255, 0.7)"
/>
<circle
id="motor2"
r="${motor2.r}"
cx="${motor2.x}"
cy="${motor2.y}"
fill="rgba(0, 255, 0, 0.7)"
/>

<circle id="target" r="${target.r}" cx="${target.x}" cy="${target.y}" fill="rgba(0, 0, 255, 0.5)" />
</g>
</svg>`;
const vMotor0 = dom.querySelector("#motor0");
const vMotor1 = dom.querySelector("#motor1");
const vMotor2 = dom.querySelector("#motor2");
const vLine0 = dom.querySelector("#line0");
const vLine1 = dom.querySelector("#line1");
const vTarget = dom.querySelector("#target");

drag(target)(d3.select(vTarget));

//motor1.fx = null;
//motor1.fx = null;

while (true) {
let [newM1Pos, newM2Pos] = updatePos(target);
motor1.fx = newM1Pos[0];
motor1.fy = newM1Pos[1];
motor2.fx = newM2Pos[0];
motor2.fy = newM2Pos[1];

vTarget.setAttribute("cx", target.fx);
vTarget.setAttribute("cy", target.fy);

vMotor0.setAttribute("cx", motor0.fx);
vMotor0.setAttribute("cy", motor0.fy);

vMotor1.setAttribute("cx", motor1.fx);
vMotor1.setAttribute("cy", motor1.fy);

vMotor2.setAttribute("cx", motor2.fx);
vMotor2.setAttribute("cy", motor2.fy);

vLine0.setAttribute("x2", motor1.fx);
vLine0.setAttribute("y2", motor1.fy);

vLine1.setAttribute("x1", motor1.fx);
vLine1.setAttribute("y1", motor1.fy);
vLine1.setAttribute("x2", motor2.fx);
vLine1.setAttribute("y2", motor2.fy);

//yield Promises.delay(3000);
yield dom;
}
}
Insert cell
Insert cell
t1 = tf.variable(tf.scalar(Math.random()))
Insert cell
t2 = tf.variable(tf.scalar(Math.random()))
Insert cell
makeRotMat = theta => {
let cosPart = tf.cos(theta).mul(
tf.tensor2d([
[1, 0],
[0, 1]
])
);
let sinPart = tf.sin(theta).mul(
tf.tensor2d([
[0, -1],
[1, 0]
])
);
return cosPart.add(sinPart); //t1Rot.dataSync()
}
Insert cell
m0Pos = {
let [m0] = nodes;
return tf.tensor2d([m0.fx, m0.fy], [1, 2]);
}
Insert cell
vec0 = tf.tensor2d([armLen, 0], [1, 2])
Insert cell
function predict(startPos, theta) {
return tf.tidy(() => {
let vecRot = tf.matMul(vec0, makeRotMat(theta));
return startPos.add(vecRot);
});
}
Insert cell
function distance(p1, p2) {
return p1.sub(p2).square().sum().sqrt();
}
Insert cell
Optimizer = tf.train.adam(0.06)
Insert cell
updatePos = (target) => {
// let [m0, m1, target] = nodes;
// 初始值 t1, 输入 px, py,输出新的 t1
// update m1 pos

// const predsYs = predict(m0Pos);
// return distance(predsYs, pPos).dataSync();
const pPos = tf.tensor2d([target.fx, target.fy], [1, 2]);
Optimizer.minimize(() => {
const m1Pos = predict(m0Pos, t1);
const m2Pos = predict(m1Pos, t2);
return distance(m2Pos, pPos);
});

let newM1Pos = predict(m0Pos, t1);
let newM2Pos = predict(newM1Pos, t2);
return [newM1Pos.dataSync(), newM2Pos.dataSync()];
}
Insert cell
Insert cell
Insert cell
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more