Jean-Yves Didier

pipe merge

......@@ -84,7 +84,8 @@ module.exports = function (grunt) {
'src/connection.js',
'src/sheet.js',
'src/eventlogicparser.js',
'src/transitionsystem.js',
'src/tokenevent.js',
'src/transitionnetwork.js',
'src/statemachine.js',
'src/application.js',
'src/arcs_module.js',
......
This diff is collapsed. Click to expand it.
......@@ -65,7 +65,7 @@ arcs_module(
console.log("Falling back on simple texture");
videoTexture = new THREE.Texture(videoSource);
}
var geometry = new THREE.PlaneGeometry(1.0, 1.0, 0.0);
var geometry = new THREE.PlaneGeometry(1.0, 1.0);
var material = new THREE.MeshBasicMaterial( {map: videoTexture, depthTest: false, depthWrite: false} );
var mesh = new THREE.Mesh(geometry, material);
var textureObject = new THREE.Object3D();
......@@ -303,7 +303,12 @@ arcs_module(
},
/** @lends ARViewer.slots */
['setWidgets','setFocal','viewAll','setSize','addScene','resetCamera','removeScene','render','keepAspectRatio'],
[
'setWidgets','setFocal','viewAll','setSize','addScene',
'resetCamera','removeScene','render','keepAspectRatio',
'setExtrinsics', 'setIntrinsics'
],
[]
);
return {ARViewer: ARViewer};
......
arcs_module(function (ARCS,three) {
var PipeNetwork = ARCS.Component.create(
function ( jsonData ) {
console.log("instanciating pipe network");
var pipeNetwork = new THREE.Object3D();
var X_OFFSET = 0; // 2.428592;
var Y_OFFSET = 0; // 48.613426;
const mmtoDeg = 0.00000001;
var createTube = function(coords, p, color, idx) {
var i, j, k;
// the father of it all
var root = new THREE.Object3D();
// computing the internal diameter of the conduct
var diametre = (p.DIAMETRE*mmtoDeg) || (100*mmtoDeg) ;
for (j=0; j < coords.length ; j++) {
if (coords[j].length >= 2) {
var path = new THREE.CurvePath();
for (k=0; k < coords[j].length-1 ; k++) {
path.add(
new THREE.LineCurve3(
new THREE.Vector3( coords[j][k][0] - X_OFFSET, coords[j][k][1] - Y_OFFSET,0),
new THREE.Vector3( coords[j][k+1][0] - X_OFFSET , coords[j][k+1][1] - Y_OFFSET, 0)
)
);
}
var geometry = new THREE.TubeGeometry(path, 10, diametre,10);
var bufferedGeometry = new THREE.BufferGeometry();
bufferedGeometry.fromGeometry(geometry);
root = new THREE.Mesh( bufferedGeometry, new THREE.MeshBasicMaterial({
color: color,
})); //new THREE.MeshBasicMaterial({color : color}) );
root.userData = idx;
}
}
return root;
};
var prepareNetwork = function ( gjObject, color ) {
if (gjObject.type === "FeatureCollection") {
if (gjObject.features === undefined) { return ; }
var i, j, k;
for (i=0; i < gjObject.features.length; i++) {
var feature = gjObject.features[i];
if (feature.geometry === undefined || feature.properties === undefined) {
return ;
}
var geometry = feature.geometry;
if (geometry.type === "MultiLineString") {
pipeNetwork.add(createTube(geometry.coordinates, feature.properties , color, i));
}
}
}
};
prepareNetwork(jsonData, 0x0000ff);
this.init = function() {
this.emit('sendSceneGraph', pipeNetwork);
};
},
['init'],
['sendSceneGraph']
);
return { PipeNetwork : PipeNetwork };
},
['deps/three.js/index']
);
\ No newline at end of file
arcs_module(
function(ARCS) {
var GPSInertialPose = new ARCS.Component.create(
function() {
var id = 0;
var pose = {
position : [ 0, 0, 0],
rotation : [ [ 1, 0, 0 ], [ 0, 1, 0 ], [ 0, 0, 1 ] ]
};
var cos = Math.cos;
var sin = Math.sin;
var meterToDegree = 0.00001;
this.setId = function(identifier) {
id = identifier;
};
this.setPosition = function(longitude, latitude) {
pose.position = [ longitude, latitude, 1.2*meterToDegree ];
this.emit('sendPose', [{ id: id, pose : pose}]);
};
// this function computes the rotation matrix according to
// https://w3c.github.io/deviceorientation/spec-source-orientation.html
this.setOrientation = function(orientation) {
var alpha = orientation.alpha;
var beta = orientation.beta;
var gamma = orientation.gamma;
pose.rotation = [[
cos(alpha)*cos(gamma) - sin(alpha)*sin(beta)*sin(gamma),
-cos(beta)*sin(alpha),
cos(gamma)*sin(alpha)*sin(beta) + cos(alpha)*sin(gamma)
], [
cos(gamma)*sin(alpha) + cos(alpha)*sin(beta)*sin(gamma),
cos(alpha)*cos(beta),
sin(alpha)*sin(gamma) - cos(alpha)*cos(gamma)*sin(beta)
], [
-cos(beta)*sin(gamma),
sin(beta),
cos(beta)*cos(gamma)
]
];
this.emit('sendPose', [{ id: id, pose : pose}]);
};
},
['setPosition','setOrientation', 'setId'],
['sendPose']
);
return { GPSInertialPose: GPSInertialPose };
}
);
\ No newline at end of file
......@@ -33,7 +33,7 @@ arcs_module(function (ARCS) {
console.log("Loop : emitting ", i);
this.emit("newIteration", i);
}
this.emit("sendToken", "end");
this.emit("endLoop");
};
/** @function Loop#newIteration
......@@ -48,7 +48,7 @@ arcs_module(function (ARCS) {
},
"setIterations", //slotList
["sendToken", "newIteration"] // signalList
["endLoop", "newIteration"] // signalList
);
......
......@@ -25,6 +25,7 @@ arcs_module(function(ARCS) {
};
var setUserMedia = function() {
console.log("video test");
if (navigator.mediaDevices !== undefined) {
navigator.mediaDevices.getUserMedia({video:{facingMode : "environment"}})
.then(handleMediaStream)
......@@ -60,6 +61,7 @@ arcs_module(function(ARCS) {
canvas = document.getElementById(canvasId);
if (video === undefined || canvas === undefined) {
console.log("video elements not defined");
return;
}
context = canvas.getContext("2d");
......
......@@ -63,10 +63,12 @@ ARCS.Context = function( ctx ) {
if (this.status >= 200 && this.status < 300) {
resolve(JSON.parse(this.responseText));
} else {
console.error(this.statusText);
reject(this.statusText);
}
};
client.onerror = function() {
console.error(this.statusText);
reject(this.statusText);
};
});
......@@ -118,6 +120,7 @@ ARCS.Context = function( ctx ) {
instanciateComponents = function() {
var p, promises=[];
console.log(components);
for (p in components) {
if (components.hasOwnProperty(p)) {
......@@ -127,18 +130,23 @@ ARCS.Context = function( ctx ) {
return ;
}
factory = factories[components[p].type];
//console.log("instanciating ", p);
try {
if (components[p].value !== undefined || components[p].url !== undefined || components[p].ref !== undefined) {
if (components[p].value !== undefined) {
console.log("instanciating ", p);
components[p].instance = new factory(components[p].value);
}
if (components[p].url !== undefined) {
promises.push(
loadDataFile(components[p].url).then(function(obj) {
// we need currying here !
var delayInstanciation = function(p,factory) {
return function(obj) {
components[p].instance = new factory(obj);
})
return Promise.resolve();
}
};
promises.push(
loadDataFile(components[p].url).then(delayInstanciation(p,factory))
);
}
if (components[p].ref !== undefined) {
......
......@@ -10,6 +10,9 @@ ARCS.Statemachine = new ARCS.Component.create(function (obj) {
// dynamic construction: properties are initial state that have properties
// that are tokens and value that are the final state
var initial = "", final = "", transitions = {}, currentState = "", self= this;
var astTokens = {}; // it keeps AST from event logic expressions
var tokenEvents = {}; // it keeps promises for tokens.
var network = {};
var addToken = function(t) {
......@@ -23,6 +26,39 @@ ARCS.Statemachine = new ARCS.Component.create(function (obj) {
}
};
/* this function aims at preparing transition networks for a given state*/
var setSheet = function(s) {
// we build promise trees using ast
var t;
if (transitions.hasOwnProperty(s)) {
tokenEvents = {};
for (t in transitions[s]) {
if (transitions[s].hasOwnProperty(t)) {
network = ARCS.TransitionNetwork.build(astTokens[t],tokenEvents).promise;
network.then(
function() {
var token;
// clean up remaining promises
for (token in tokenEvents) {
if (tokenEvents.hasOwnProperty(token)) tokenEvents[token].abort();
}
// then activate next sheet
setSheet(transitions[s][t]);
}
);
}
}
}
currentState = s;
self.emit('requestSheet', currentState);
if (currentState === final) {
self.emit('requestTermination');
}
};
/**
* Sets the initial state of the statemachine
* @param string {string} name of the initial state
......@@ -46,39 +82,22 @@ ARCS.Statemachine = new ARCS.Component.create(function (obj) {
var re = /([A-Za-z_]\w*)/g;
var t, tsd, ts, tsc;
try {
var tsd = ARCS.EventLogicParser.parse(token);
if (typeof tsd === "string") {
if (transitions[start] === undefined) {
transitions[start] = {};
}
transitions[start][tsd] = end;
addToken(tsd);
} else {
// we will start to build here a transition system corresponding to
// the "token" object.
// first we look for tokens
while( (t = re.exec(token)) !== null) {
addToken(t[0]);
}
// then we build the transition system.
ts = ARCS.TransitionSystem.build(tsd);
tsc = ts.clone(start + '_' + end + '_');
tsc.renameState(tsc.initial, start);
tsc.renameState(tsc.final, end);
// then, let's fuse the transition systems !
tsc.visitTransitions( function ( s, t, e) {
if (transitions[s] === undefined) {
transitions[s] = {};
}
transitions[s][t] = e;
});
}
}
astTokens[token] = tsd;
if (transitions[start] === undefined) {
transitions[start] = {};
}
transitions[start][token] = end;
} catch (e) { }
};
/**
......@@ -87,14 +106,8 @@ ARCS.Statemachine = new ARCS.Component.create(function (obj) {
* @param token {string} name of the token
*/
this.setToken = function (token) {
if (transitions[currentState] !== undefined) {
if (transitions[currentState][token] !== undefined) {
currentState = transitions[currentState][token];
this.emit('requestSheet', currentState);
if (currentState === final) {
this.emit('requestTermination');
}
}
if (tokenEvents.hasOwnProperty(token)) {
tokenEvents[token].accept();
}
};
/**
......@@ -133,8 +146,8 @@ ARCS.Statemachine = new ARCS.Component.create(function (obj) {
* the initial state (by default, it is the departure of the first transition
*/
this.start = function () {
currentState = initial;
this.emit('requestSheet', currentState);
console.log("statemachine", this, initial,obj);
setSheet(initial);
};
......@@ -142,7 +155,6 @@ ARCS.Statemachine = new ARCS.Component.create(function (obj) {
if (obj !== undefined) {
initial = obj.initial;
final = obj.final;
//transitions = obj.transitions;
this.setTransitions(obj.transitions);
currentState = "";
}
......
// this class creates a promise that can be deferred as long as necessary.
// calls to accept or reject will solve the promise.
ARCS.TokenEvent = function() {
var refResolve;
var refReject;
this.promise = new Promise(function(resolve, reject) {
refResolve = resolve;
refReject = reject;
});
this.accept = function() {
refResolve();
};
this.abort = function() {
refReject();
};
};
\ No newline at end of file
ARCS.TokenManager = function() {
var expressions = {};
var collectedTokens = {};
var TokenNode = function() {
var child = null;
var next = null;
var token = null;
var op = null;
this.or = function() {
};
this.and = function() {
};
this.eval = function() {
if (op !== null) {
} else {
}
};
};
this.addExpression = function (expr) {
try {
var tsd = ARCS.EventLogicParser.parse(expr);
} catch (e) { }
};
this.collect = function (token) {
collectedTokens[token] = true;
};
this.clearTokens = function() {
collectedTokens = {};
};
this.checkExpression = function(expr) {
};
};
\ No newline at end of file
/* the aim of the transition network is to build a network of promises */
ARCS.TransitionNetwork = function() {
// object storing token events (that is to say references to promises)
this.promise = {};
this.and = function(tn) {
this.promise = Promise.all([this.promise, tn.promise]);
return this;
};
this.or = function(tn) {
this.promise = Promise.race([this.promise, tn.promise]);
return this;
};
};
ARCS.TransitionNetwork.build = function(tree, tokenEvents) {
var res;
var tmpTN;
var rightTN;
if (typeof tree === "string") {
// here we have a terminal string i.e. a token event
var tokenEvent;
if (tokenEvents.hasOwnProperty(tree)) {
tokenEvent = tokenEvents[tree];
} else {
tokenEvents[tree] = tokenEvent = new ARCS.TokenEvent();
}
var tn = new ARCS.TransitionNetwork();
tn.promise = tokenEvent.promise;
return tn;
}
res = ARCS.TransitionNetwork.build(tree[0],tokenEvents);
for (i=1; i < tree.length; i++) {
if (tree[i].hasOwnProperty('and')) {
rightTN = ARCS.TransitionNetwork.build(tree[i]['and'], tokenEvents);
tmpTN = res.and(rightTN);
} else {
if (tree[i].hasOwnProperty('or')) {
rightTN = ARCS.TransitionNetwork.build(tree[i]['or'], tokenEvents);
tmpTN = res.or(rightTN);
} else {
console.warn('[ARCS] Illegal tree');
}
}
res = tmpTN;
}
return res;
};
\ No newline at end of file
/*
* The purpose of this class is to build a transition system in order to fully
* ascertain some "event" logic
*/
ARCS.TransitionSystem = function(a, b, c) {
this.initial = "" ;
this.final = "";
var transitions = {};
if ( a !== undefined) {
if ( (b === undefined || c === undefined)) {
this.initial = "a$";
this.final = "z$";
transitions[this.initial] = {};
transitions[this.initial][a] = this.final;
} else {
this.initial = a;
this.final = c;
transitions[this.initial] = {};
transitions[this.initial][b] = this.final;
}
}
this.visitTransitions = function( closure ) {
var p,t;
for (p in transitions) {
if (transitions.hasOwnProperty(p)) {
for (t in transitions[p]) {
if (transitions[p].hasOwnProperty(t)) {
closure(p,t,transitions[p][t]);
}
}
}
}
}
this.clone = function(pf) {
// checked
var prefix = pf || "";
var res = new ARCS.TransitionSystem();
res.initial = prefix + this.initial;
res.final = prefix + this.final;
this.visitTransitions( function(s, t, e) {
res.addTransition(prefix + s, t, prefix + e);
});
return res;
};
this.fuse = function(ts, i, f) {
// checked
var res = ts.clone();
this.visitTransitions( function(s, t, e) {
res.addTransition(s, t, e);
});
if (i === undefined) {
res.initial = this.initial;
} else {
res.initial = i;
}
if (f === undefined) {
res.final = this.final;
} else {
res.final = f;
}
return res;
};
this.hasState = function(s) {
if (this.initial === s || this.final === s || transitions.hasOwnProperty(s)) {
return true;
}
try {
this.visitTransitions( function (s1, t, e) {
if ( e === s) throw '!';
});
} catch ( e ) {
if (e === '!')
return true;
}
return false;
};
this.renameState = function (currentName, newName) {
if (this.hasState(newName)) {
// this is bad !
console.error("This transition system is corrupt !");
}
if (this.initial === currentName) {
this.initial = newName;
}
if (this.final === currentName) {
this.final = newName;
}
if (transitions.hasOwnProperty(currentName)) {
transitions[newName] = transitions[currentName];
delete transitions[currentName];
}
this.visitTransitions( function (s, t, e) {
if ( e === currentName ) {
transitions[s][t] = newName;
}
});
};
this.dump = function () {
console.log('@ = ' + this.initial + ', + = ' + this.final);
this.visitTransitions( function(s, t, e) {
console.log(' ' + s + '\t---\t'+ t +'\t-->\t' + e);
});
};
this.getStates = function() {
// check
var states = [];
// then we start looking for states
this.visitTransitions(function (s, t, e) {
if (states.indexOf(s) < 0) {
states.push(s);
}
if (states.indexOf(e) < 0) {
states.push(e);
}
});
return states;
}
this.addTransition = function( start, token, end) {
if ( ! transitions.hasOwnProperty(start)) {
transitions[start] = {};
}
transitions[start][token] = end;
};
// let's make a AND operation
this.and = function(ts) {
//check
// letters will create disambiguation
var i;
// first, let's create two identical trees
var leftTS1 = this.clone('i');
var leftTS2 = this.clone('j');
var rightTS;
// then, we fuse the trees together.
var res = leftTS1.fuse(leftTS2, leftTS1.initial, leftTS2.final);
var tmpFuse;
var states = this.getStates();
for( i = 0; i < states.length; i++) {
rightTS = ts.clone('k'+i);
rightTS.renameState(rightTS.initial, 'i'+ states[i]);
rightTS.renameState(rightTS.final, 'j'+ states[i]);
tmpFuse = res.fuse(rightTS);
res = tmpFuse;
}
return res;
};
// let's make a OR operation
this.or = function(ts) {
// checked
var leftTS = this.clone('s');
var rightTS = ts.clone('t');
rightTS.renameState(rightTS.initial, leftTS.initial);
rightTS.renameState(rightTS.final, leftTS.final);
return leftTS.fuse(rightTS);
};
};
// tree is the one obtained by parsing expressions
ARCS.TransitionSystem.build = function( tree, d) {
var depth = d || 1;
var counter = 1;
var i;
var res;
var tmpTS;
var rightTS;
if (typeof tree === "string") {
return new ARCS.TransitionSystem(tree).clone('w0d' + depth);
}
// TODO: depth is not handled in subexpression prefixes.
// This may results in name clashes for intermediate transformations (or not)
res = ARCS.TransitionSystem.build(tree[0], depth + 1);
for (i=1; i < tree.length; i++) {
if (tree[i].hasOwnProperty('and')) {
rightTS = ARCS.TransitionSystem.build(tree[i]['and'], depth + 1).clone('w' + counter++);
tmpTS = res.and(rightTS);
} else {
if (tree[i].hasOwnProperty('or')) {
rightTS = ARCS.TransitionSystem.build(tree[i]['or'], depth + 1).clone('w' + counter++);
tmpTS = res.or(rightTS);
} else {
console.warn('[ARCS] Illegal tree');
}
}
res = tmpTS;
}
return res;
};
\ No newline at end of file
......@@ -25,7 +25,7 @@
],
"connections" : [
{ "source":"loop", "signal":"newIteration", "destination":"dint", "slot":"display" },
{ "source":"loop", "signal":"sendToken", "destination":"statemachine", "slot":"end" }
{ "source":"loop", "signal":"endLoop", "destination":"statemachine", "slot":"end" }
],
"cleanups" : []
},
......@@ -36,7 +36,7 @@
],
"connections" : [
{ "source":"loop", "signal":"newIteration", "destination":"dint", "slot":"display" },
{ "source":"loop", "signal":"sendToken", "destination":"statemachine", "slot":"end" }
{ "source":"loop", "signal":"endLoop", "destination":"statemachine", "slot":"end" }
],
"cleanups" : []
}
......
This diff could not be displayed because it is too large.
......@@ -5,6 +5,10 @@
}
body, html {
height: 100%;
}
body {
font-family: sans-serif;
......
......@@ -24,7 +24,7 @@
"value" : {
"initial": "init",
"transitions" : {
"init" : { "next" : "start"}
"init" : { "video&data" : "start"}
}
}
}
......@@ -48,7 +48,9 @@
],
"connections": [
{ "destination": "viewer", "slot": "addScene", "source": "pipeNetwork", "signal": "sendSceneGraph" },
{ "destination": "statemachine", "slot": "next", "source": "pipeNetwork", "signal": "sendSceneGraph" }
{ "destination": "statemachine", "slot": "data", "source": "pipeNetwork", "signal": "sendSceneGraph" },
{ "destination": "statemachine", "slot": "video", "source": "video", "signal": "onReady"}
],
"cleanups": [
]
......