I'm using Wikitude (on Android with the Javascript APIs) to show a transparent video inside of the AR experience. I don't have a marker on which putting my video. That video has its coordinates (relative to the user's position) and I want to place it on an exact position so that the user can see it when its device is pointing towards that direction.
In order to do that I used an AR.RelativeLocation object and placed a VideoDrawable on a particular position.
// the location
var location = new AR.RelativeLocation(null, 5, 5, 0);
// the video
var video = new AR.VideoDrawable("assets/transparentVideo.mp4", 5, {
scale: {
x: 1,
y: 1,
z: 1
},
isTransparent: true,
onLoaded: this.worldLoaded
});
video.play(0) // the video starts immediately
// the GeoObject showing the video
var obj = new AR.GeoObject(location, {
drawables: {
cam: [video]
}
});
The problem is that the video is not stable at all. When I turn my device I see the video approximately on its position but it's not fixed: it moves following my camera movements for a while as if it would placed by using the movement sensor rather than the gyroscope. Is there a possibility to stabilize it?
The Wikitude Android SDK is not using the gyroscope at the moment but a combination of accelerometer and compass to calculate the orientation. There is also no method to change the accuracy. What you can try is calibrating your compass like described here: https://support.google.com/maps/answer/6145351?hl=en or here: https://android.stackexchange.com/questions/10145/how-can-i-calibrate-the-compass-on-my-phone and try to keep a distance to things that can influence the compass accuracy like other electrical devices.
Related
Im using the latest UX SDK 4.12 on Android with DJI MAVIC 2 enterprise.
I upload 2 WayPoints in a WayPointMission. The aircraft is heading in the direction of the flight:
WaypointMissionHeadingMode.AUTO
Once the last waypoint is reached, I send startShootPhoto command to take a single photo.
For some strange reason, the aircraft turns to the absolute north or west north before taking the photo and then turns back to the original heading position.
Can any one please suggest how to keep the aircraft heading in the same direction when taking the photo?
I found the following attributes to control the Flight Orientation and it solved the problem. It seems that camera was not the one causing the aircraft to turn.
aircraft.getFlightController().setFlightOrientationMode(FlightOrientationMode.AIRCRAFT_HEADING, new CommonCallbacks.CompletionCallback() {
#Override
public void onResult(DJIError djiError) {
Log.i(TAG, "FlightOrientationMode " + djiError);
}
});
WaypointMissionHeadingMode mHeadingMode = WaypointMissionHeadingMode.AUTO;
waypointMissionBuilder = new WaypointMission.Builder().finishedAction(mFinishedAction)
.headingMode(mHeadingMode)
.autoFlightSpeed(SPEED)
.maxFlightSpeed(SPEED)
.flightPathMode(WaypointMissionFlightPathMode.NORMAL);
I'm developing an app using ARCore. In this app I need:
1) to place an object always staying at the same pose in world space. Following the "Working with Anchors" article recommendations (https://developers.google.com/ar/develop/developer-guides/anchors) I'm attaching an anchor to the ARCore Session. That is, I'm not using Trackables at all.
2) as a secondary requisite the object must be placed automatically, that is, without tapping on the screen.
I've managed to solve the two requisites, having now the object "floating" in front of me, this way (very common code):
private void onSceneUpdate(FrameTime frameTime) {
...
if (_renderable!=null && _anchorNode==null) {
float[] position = {0f,0f,-10f};
float[] rotation = {0,0,0,1};
//
Anchor anchor=_arFragment.getArSceneView().getSession().createAnchor(new Pose(position,rotation));
//
_anchorNode = new AnchorNode(anchor);
_anchorNode.setRenderable(_renderable);
_anchorNode.setParent(_arFragment.getArSceneView().getScene());
_anchorNode.setLocalScale(new Vector3(0.01f,0.01f,0.01f)); //cm -> m
...
}
As i want the object to be on the floor, I need to find out what the height of my physical (device) camera above the floor is, in order to subtract that number from the current object's Y coordinate:
float[] position = {0f,HERE_THE_VALUE_TO_SUBTRACT_FROM_CAMERA_HEIGHT,-10f};
Certainly, it's an easy implementation when plane Trackables are used but here I have the requisites above-named.
I've managed to solve the two requisites, having now the object "floating" in front of me.
As i want the object to be on the floor, I need to find out what the height of my physical (device) camera above the floor is, in order to subtract that number from the current object's Y coordinate.
Trying with different camera/device Pose retrieval APIs, namely: frame.getAndroidSensorPose(), frame.getCamera().getPose() and frame.getCamera().getDisplayOrientedPose() are showing not valid values.
Thanks for your advice.
P.S.:Certainly, it's an easy implementation when plane Trackables are used but here I have other requisites, as above-named.
EDIT after Michael Dougan comments.
Well I think we have then two ways to achieve the requisites:
1) leave the code w/o changes, keeping on using the Session Anchor, asking the user to launch the app and the to follow a "calibration process" which the device on the floor. As this is a professional use app, and not a consumer one, we think it is perfectly suitable;
2) go ahead with the good-and-old Trackables, by means of the usual floor as an anchor, including the pose of that anchor in the calculation of the position of the 3D model.
I'm having a hard time to pan a view of a gameObject in Unity3d. I'm new to scripting and I'm trying to develop an AR (Augmented Reality) application for Android.
I need to have a gameObject (e.g. a model of a floor), from the normal top down view, rendered to a "pseudo" iso view, inclined to 45 degrees. As the gameObject is inclined, I need to have a panning function on its view, utilizing four (4) buttons (for left, right, forward(or up), backward(or down)).
The problem is that, I cannot use any of the known panning script snippets around the forum, as the AR camera has to be static in the scene.
Need to mention that, I need the panning function to be active only at the isometric view, (which I already compute with another script), not on top down view. So there must be no problem with the inclination of the axes of the gameObject, right?
Following, are two mockup images of the states, the gameObject (model floor) is rendered and the script code (from Unity reference), that I'm currently using, which is not very much functional for my needs.
Here is the code snippet, for left movement of the gameObject. I use the same with a change in -, +speed values, for the other movements, but I get it only move up, down, not forth, backwards:
#pragma strict
// The target gameObject.
var target: Transform;
// Speed in units per sec.
var speedLeft: float = -10;
private static var isPanLeft = false;
function FixedUpdate()
{
if(isPanLeft == true)
{
// The step size is equal to speed times frame time.
var step = speedLeft * Time.deltaTime;
// Move model position a step closer to the target.
transform.position = Vector3.MoveTowards(transform.position, target.position, step);
}
}
static function doPanLeft()
{
isPanLeft = !isPanLeft;
}
It would be great, if someone be kind enough to take a look at this post, and make a suggestion on how this functionality can be coded the easiest way, as I'm a newbie?
Furthermore, if a sample code or a tutorial can be provided, it will be appreciated, as I can learn from this, a lot. Thank you all in advance for your time and answers.
If i understand correctly you have a camera with some fixed rotation and position and you have a object you want to move up/down/left/right from the cameras perspective
To rotated an object to a set of angles you simply do
transform.rotation = Quaternion.Euler(45, 45, 45);
Then to move it you use the cameras up/right/forward in worldspace like this to move it up and left
transform.position += camera.transform.up;
transform.position -= camera.transform.right;
If you only have one camera in your scene you can access its transform by Camera.main.transform
An example of how to move it when someone presses the left arrow
if(Input.GetKeyDown(KeyCode.LeftArrow))
{
transform.position -= camera.transform.right;
}
I'm new to scripting and I'm trying really hard to make an AR application for Android mobiles in Unity3d. I came up to a problem, that cannot solve no matter what I've though off.
Here is the situation. I have an AR camera scripted with the NyARToolkit plugin for Augmented Reality for Unity3d.
This AR camera, tagged as "MainCamera", needs to get switched off, when a certain distance is reached (meaning moving away the android phone) form the marker that renders the model on it.
When this distance is reached, I want to set off "MainCamera" and load another unity scene.
The following code is what I've tried so far, without much success. Need to mention that, this script is attached on "MainCamera", and this is the gameObject that needs to be disabled.
Here is the script:
#pragma strict
var mainCamera : Transform;
var camera : GameObject;
function Update() {
var distance = Vector3.Distance(mainCamera.position, transform.position);
if(distance<0) {
Debug.Log("CloseUp camera is on : " + distance);
}
if(distance > 1) {
Debug.Log("CloseUp camera is off : " + distance);
Camera.main.gameObject.SetActiveRecursively(false);
}
}
Can somebody, take a look at my code snippet and post a working edit, so I can get the distance right and set the camera off when user moves the android mobile away form the marker?
Thank you all in advance for your answers.
"Edit 1"
I know I'm not even close to the function need to make work on mobile, but this link, will give you a view of that functionality. I need to get the distance from the marker to mobile first, and if that distance is e.g. above 1.5 m, the AR camera should be switched off and a new level should be loaded.
You didn't mention what exactly wasn't working. Based on what I could piece together from your post and the code sample you provided you just need to add the level loading code.
#pragma strict
var mainCamera : Transform;
var camera : GameObject;
function Update() {
var distance = Vector3.Distance(mainCamera.position, transform.position);
if(distance<0) {
Debug.Log("CloseUp camera is on : " + distance);
}
if(distance > 1) {
Debug.Log("CloseUp camera is off : " + distance);
// If you are loading a new scene you likely don't need to bother turning off the camera
Camera.main.gameObject.SetActiveRecursively(false);
Application.LoadLevel ("nameOfTheLevelToLoad");
}
}
Here's the code I use...
float DistanceMainCamPosSpawnedPrefab =
Vector3.Distance(MainCam.transform.position,
m_SpawnedOnePrefab.transform.position); // the m_SpawnedOnePrefab would be your marker
if (DistanceMainCamPosSpawnedPrefab > .3f && DistanceMainCamPosSpawnedPrefab <
.5f)
{
// run your code here
}
I'm trying to detect shaking event using Cordova 2.2.0 for android devices.
I found some question related to this topic but t's in native code for example this question and this question.
Does anyone knows how to detect this event using phonegap Cordova ? or I should write a plugin ?
You can try shake.js. Ive been looking into it, but not implemented it. It looks promising.
Use the accelerometer to store the previous values (x, y and z). Defining the thresholds (x,y,z) you can detect shaking if the different betwen the previosValues and the actual once (event.value[i] where i=x,y ans z) is higher than the thresholds.
You also can use the magnitude of the acceleration values (Acc=sqrt(x*x+y*y+z*z)) or the timestamp to obtain better results.
Cordova offers the device-motion plugin, which (surprisingly) exposes a navigator.accelerometer object, instead of aligning with the W3C deviceorientation/devicemotion standard published since 2011.
When the device lays flat on a surface, the (x, y, z) acceleration will be (0, 0, 9.81). The basic idea for detecting a shake is to watch the acceleration with a given frequency, calculate the delta from the previous sample, and decide if it's larger than a threshold.
navigator.accelerometer.watchAcceleration(onSuccess, onError, { frequency: 300 });
// Assess the current acceleration parameters to determine a shake
function onSuccess(acceleration) {
var accelerationChange = {};
if (previousAcceleration.x !== null) {
accelerationChange.x = Math.abs(previousAcceleration.x - acceleration.x);
accelerationChange.y = Math.abs(previousAcceleration.y - acceleration.y);
accelerationChange.z = Math.abs(previousAcceleration.z - acceleration.z);
}
previousAcceleration = {
x: acceleration.x,
y: acceleration.y,
z: acceleration.z
};
if (accelerationChange.x + accelerationChange.y + accelerationChange.z > sensitivity) {
// Shake detected, invoke callback
}
}
A plugin doing that is Lee Crossley's cordova-plugin-shake-detection.