Argon.js: Error: A frame state has not yet been received - aframe

I am attempting to use argon.js server side so that I can convert lla coordinates to a predefined reference frame. I'm not rendering any graphics of course, I'm just using it to convert values. See SO question
Using Geo-coordintes Instead of Cartesian to Draw in Argon and A-Frame
for details.
Per that thread, I am trying to create a cesium entity for a fixed coordinate which I will later use to create other entities relative to it. When I do, everything runs until I get to the last line of the program var gtrefEntityPose = app.context.getEntityPose(gtrefEntity); where I receive Error: A frame state has not yet been received.
At first I thought this might be due to the setting the default reference entity to app.context.setDefaultReferenceFrame(app.context.localOriginEastUpSouth); since I did not have a local user yet due to it being server side. I looked up the documentation for setDefaultReferenceFrame as well as the possibility that I might need to use convertEntityReferenceFrame as well as the source code for each, but I am unable to make sense of it given my knowledge of the program.
I've put the error as well as my application code below.
Thanks for your help!
/home/path/to/folder/node_modules/#argonjs/argon/dist/argon.js:4323
if (!cesium_imports_1.defined(this.serializedFrameState)) throw new Error(
^
Error: A frame state has not yet been received
at ContextService.Object.defineProperty.get [as frame] (/home/path/to/folder/node_modules/#argonjs/argon/dist/argon.js:4323:89)
at ContextService.getTime (/home/path/to/folder/node_modules/#argonjs/argon/dist/argon.js:4343:32)
at ContextService.getEntityPose (/home/path/to/folder/node_modules/#argonjs/argon/dist/argon.js:4381:37)
at Object.<anonymous> (/home/path/to/folder/test.js:27:35)
at Module._compile (module.js:460:26)
at Object.Module._extensions..js (module.js:478:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Function.Module.runMain (module.js:501:10)
at startup (node.js:129:16)
Here is my code:
var Argon = require('#argonjs/argon');
var Cesium = Argon.Cesium;
var Cartesian3 = Cesium.Cartesian3;
var ConstantPositionProperty = Cesium.ConstantPositionProperty;
var ReferenceFrame = Cesium.ReferenceFrame;
var ReferenceEntity = Cesium.ReferenceEntity;
//var degToRad = THREE.Math.degToRad;
const app = Argon.init();
app.context.setDefaultReferenceFrame(app.context.localOriginEastUpSouth);
var data = { lla : { x : -84.398881, y : 33.778463, z : 276 }};
var gtref = Cartesian3.fromDegrees(data.lla.x, data.lla.y, data.lla.z);
var options = { position: new ConstantPositionProperty(gtref, ReferenceFrame.FIXED),
orientation: Cesium.Quaternion.IDENTITY
};
var gtrefEntity = new Cesium.Entity(options);
var gtrefEntityPose = app.context.getEntityPose(gtrefEntity);

As it's currently designed, argon.js won't work server-side. In particular, the local coordinate frame is not set until argon.js has obtained a geospatial position and orientation for the "user", which is obtained either from Argon4 (if you are running in the Argon4 web browser) or from a combination of the web geolocation and deviceorientation API's (if you are running in a different browser).
With a full 6D pose (3D position + 3D orientation), the system does not know the position and viewing direction of the user, and cannot establish a local euclidean coordinate frame. Thus app.context.localOriginEastUpSouth remains undefined (the Cesium Entity exists, but it's position and orientation are not set), and app.context.getEntityPose(gtrefEntity) will fail.
To use argon.js server-side, you would need to modify it to allow the program to manually set the position and orientation of the viewer. I could imagine doing that, and even using it in a system that has the mobile client periodically sending the pose back to the server (via socket.io, for example). In situations where you don't care about the viewing direction (e.g., if you're just worrying about the position of the user) you could just set the orientation to identity and ignore the orientation in the returned pose.

Related

Reading JS library from CDN within Mirth

I'm doing some testing around Mirth-Connect. I have a test channel that the datatypes are Raw for the source and one destination. The destination is not doing anything right now. In the source, the connector type is JavaScript Reader, and the code is doing the following...
var url = new java.net.URL('https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.fp.min.js');
var conn = url.openConnection();
conn.setRequestMethod('GET');
if(conn.getResponseCode() === 200) {
var body = org.apache.commons.io.IOUtils.toString(conn.getInputStream(), 'UTF-8');
logger.debug('CONTENT: ' + body);
globalMap.put('_', body);
}
conn.disconnect();
// This code is in source but also tested in destination
logger.debug('FROM GLOBAL: ' + $('_')); // library was found
var arr = [1, 2, 3, 4];
var _ = $('_');
var newArr = _.chunk(arr, 2);
The error I'm getting is: TypeError: Cannot find function chunk in object.
The reason I want to do this is to build custom/internal libraries with unit test and serve them with an internal/company CDN and allow Mirth to consume them.
How can I make the library available to Mirth?
Rhino actually has commonjs support, but mirth doesn't have it enabled by default. Here's how you can use it in your channel.
channel deploy script
with (JavaImporter(
org.mozilla.javascript.Context,
org.mozilla.javascript.commonjs.module.Require,
org.mozilla.javascript.commonjs.module.provider.SoftCachingModuleScriptProvider,
org.mozilla.javascript.commonjs.module.provider.UrlModuleSourceProvider,
java.net.URI
)) {
var require = new Require(
Context.getCurrentContext(),
this,
new SoftCachingModuleScriptProvider(new UrlModuleSourceProvider([
// Search path. You can add multiple URIs to this array
new URI('https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/')
],null)),
null,
null,
true
);
} // end JavaImporter
var _ = require('lodash.min');
require('lodash.fp.min')(_); // convert lodash to fp
$gc('_', _);
Note: There's something funky with the cdnjs lodash fp packages that don't detect the environment correctly and force that weird two stage import. If you use https://cdn.jsdelivr.net/npm/lodash#4.17.15/ instead you only need to do var _ = require('fp'); and it loads everything in one step.
transformer
var _ = $gc('_');
logger.info(JSON.stringify(_.chunk(2)([1,2,3,4])));
Note: This is the correct way to use fp/chunk. In your OP you were calling with the standard chunk syntax.
Additional Commentary
I think it's probably ok to do it this way where you download the library once at deploy time and store it in the globalChannelMap, then retrieve it from the map where needed. It would probably also work to store the require object itself in the map if you wanted to call it elsewhere. It will cache and reuse the object created for future calls to the same resource.
I would not create new Require objects anywhere but the deploy script, or you will be redownloading the resource on every message (or every poll in the case of a Javascript Reader.)
Edit: I guess for an internal webhost, this could be desirable in a Javascript Reader if you intend for it to pick up changes immediately on the next poll without a redeploy, assuming you would be upgrading the library in place instead of incrementing a version
The benefit to using Code Templates, as Vibin suggested is that they get compiled directly into your channel at deploy time and there is no additional fetching step at runtime. Making the library available is as simple as assigning it to your channel.
Even though importing third party libraries could be an option, I was actually looking into this for our team to write our own custom functions, write unit-test for them, and lastly be able to pull that code inside Mirth. I was experimenting with lodash but it was not my end goal to use it, it is. My solution was to do a REST GET call with java in the global script. Your URL would be the GitHub raw URL of the code you want to pull in. Same code of my original question but like I said, the URL is the raw GitHub URL for the function I want to pull in.

Swift 4 and Geofire: dealing with invalid geolocation error

I am using the swift 4 language and geofire library to find points on the map within 3000 km of where I am.
When the query encounters the latitude point 90,500 and longitude 100,000 the following error appears: "Not a valid geo location". The crash happens in the "query.observe(.keyEntered" line
query? = geoFire.query (at: self.currentLocation.newLocation !, withRadius: self.distance) {
//code
}
//The crash happens on this line:
var queryHandler = query.observe(.keyEntered, with: {(key, location) in
//Code
})
My question is, how can I handle this kind of error? Do I need to remove all incorrect coordinates from the database? Apparently the function "observe(.keyEntered" does not allow to handle exceptions. I would like to handle the exceptions without the app breaking
It seems like you're hitting the problem described in this issue on the Github repo: https://github.com/firebase/geofire-objc/issues/64
From what I see there, the only option is to reduce the radius of the query.

How to get features from vector layer in Openlayers 3

I am trying to get the features from my vector layer. The vector layer is composed from a GeoJSON document loaded via Geoserver. I tried vector.features but in vain. Could anyone help with this?
The architecture of OL3 distinguishes between a layer and their source. So to get access to the features of a layer you first have to access the source of the layer. This is done via:
var source = layer.getSource();
In case of a vector layer you will than get a ol.source.Vector object. From this object you can access your features via:
var features = source.getFeatures();
Further you got the possibility to access special features via getFeatureById(id) or getFeaturesAtCoordinate(coordinate). For more information see the api documentation http://openlayers.org/en/v3.4.0/apidoc/ol.source.Vector.html
this.vectorLayer = new VectorLayer({
source: new VectorSource({
url:'https://json.extendsclass.com/bin/d4f21e1dd8ed',
format: new GeoJSON()
}),
});
this.maps.addLayer(this.vectorLayer)
var source = this.vectorLayer.getSource();
var features = source.getFeatures();
console.log(features,'FeatureData');
When we getting features from source then its returning 0 array you can see in image click here for image
and in my url one feature available.

When I connect to firebase, I only see the structures and no devices (Nest API)

I am trying to read basic information about thermostats using the methods in the thermostat control example (https://developer.nest.com/documentation/control), but when I connect to firebase I only see the structure object (which only contains name, away, smoke_co_alarms, structure_id and thermostats) in the snapshot– There is no devices object. I am connecting to firebase using
var nestToken = $.cookie('nest_token');
var dataRef = new Firebase('wss://developer-api.nest.com/');
dataRef.auth(nestToken);
I tried to connect directly to devices using wss://developer-api.nest.com/devices, but that only returns an undefined data-structure.
I've also tried connecting to firebase using https://developer-api.nest.com/ and https://developer-api.nest.com/, but they raised an authorization error and caused my javascript to go into an infinite loop sending requests.
I'm reading data using:
dataRef.on('value', function (snapshot) {
var data = snapshot.val();
structure = firstChild(data.structures);
console.log(data);
console.log(data.structures);
console.log(data.devices);
console.log(data.devices.thermostats);
console.log(structure.thermostats);
};
Lastly, I tried it on an account with real devices and one with virtual devices, so I know that couldn't be causing it (even though I didn't expect it to).
Any ideas what I am doing wrong? The issue couldn't be in my App.js file, could it? Is there some configuration I need to do on the user's end in addition to the authentication? I get the feeling it's probably something really simple that's staring me in the face.
So I figured it out: It's a permissions issue. When my client-profile was setup, it only requested permission to read the away/home status. So when I query Firebase it only returns the a snapshot with structure because that is where the away/home status can be read. So, in summary, if you're not seeing the devices structure, even though devices are associated with the user, check your client permissions.
Using (some of) your code, I have no trouble seeing the devices object:
var dataRef = new Firebase('wss://developer-api.nest.com');
dataRef.auth(nestTokenLive);
dataRef.on('value', function (snapshot) {
var data = snapshot.val();
console.log(data);
console.log(data.devices);
});
Results in:
> Object {devices: Object, structures: Object}
> Object {thermostats: Object}

Loading Sound gives exception on Sound.id3

When loading a MP3 to a flash.media.Sound object the id3 property gives an error:
SecurityError: Error #2000: No active security context.
Offcourse, like many errors in Flex, the Flex documentation doesn't mention a thing about this, except that it exists...
The MP3 is valid (i've checked it with MediaPlayer and iTunes), the Sound object is in a good state (bytesTotal and bytesLoaded both reflect the correct amount of bytes).
Has anyone had this problem too? Any solutions or suggestions?
Your MP3 should be fine.
If you want to access more data about your mp3 file, rather than just play, you will need a policy file that allows it. Similar to loading an image, if you just add it to the display it and don't access the pixels, it's all good, but if you want to access the pixels you should have permission(a crossdomain xml).
For images, when you call the load image, you can pass a LoaderContext in which you explicitly say you want to check for a crossdomain.xml file and get access to the content.
Similarly you should create a SoundLoaderContext with the second parameter set to true(to check) and use that in the sound load call.
e.g.
var snd:Sound = new Sound();
var req:URLRequest = new URLRequest("yourSound.mp3");
var context:SoundLoaderContext = new SoundLoaderContext(0, true);
snd.load(req, context);
snd.play();
For ID3 data you should listen for the ID3 event:
sound.addEventListener(Event.ID3, onID3);
function onID3(event:Event) {
for(var i in sound.id3)
trace('prop: ' + i + ' value: ' + sound.id3[i]);
}
For more info, you might find the mp3infoutil library handy.
HTH,
George

Resources