problem situation: Creating AR-Visualizations always at the same place (on a table) in a comfortable way. We don't want the customer to place the objects themselves like in countless ARCore/ARKit examples.
I'm wondering if there is a way to implement those steps:
Detect marker on the table
Use the position of the marker as the initial position of the AR-Visualization and go on with SLAM-Tracking
I know there is something like an Marker-Detection API included in the latest build of the TangoSDK. But this technology is limited to a small amount of devices (two to be exact...).
best regards and thanks in advance for any idea
I am also interested in that topic. I think the true power of AR can only be unleashed when paired with environment understanding.
I think you have two options:
wait for the new Vuforia 7 to be released and supposedly it is going to support visual markers with ARCore and ARKit.
Engage CoreML / Computer Vision - in theory it is possible but I haven't seen many examples. I think it might be a bit difficult to start with (e.g. build and calibrate model).
However Apple have got it sorted:
https://youtu.be/E2fd8igVQcU?t=2m58s
if using Google Tango, you can implement this using the built in Area Descriptions File (ADF) system.
The system has a holding screen and you are told to "walk around". Within a few seconds, you can relocalise to an area the device has previously been. (or pull the information from a server etc..)
Googles VPS (Visual Positioning Service) is a similar Idea, (closed Beta still) which should come to ARCore. It will, as far as I understand, allow you to localise a specific location using the camera feed from a global shared map of all scanned locations. I think, when released, it will try to fill the gap of an AR Cloud type system, which will solve these problems for regular developers.
See https://developers.google.com/tango/overview/concepts#visual_positioning_service_overview
The general problem of relocalising to a space using pre-knowledge of the space and camera feed only is solved in academia and other AR offerings, hololens etc... Markers/Tags aren't required.
I'm unsure, however, which other commercial systems provide this feature.
This is what i got so far for ARKit.
#objc func tap(_ sender: UITapGestureRecognizer){
let touchLocation = sender.location(in: sceneView)
let hitTestResult = sceneView.hitTest(touchLocation, types: .featurePoint)
if let hitResult = hitTestResult.first{
if first == nil{
first = SCNVector3Make(hitResult.worldTransform.columns.3.x, hitResult.worldTransform.columns.3.y, hitResult.worldTransform.columns.3.z)
}else if second == nil{
second = SCNVector3Make(hitResult.worldTransform.columns.3.x, hitResult.worldTransform.columns.3.y, hitResult.worldTransform.columns.3.z)
}else{
third = SCNVector3Make(hitResult.worldTransform.columns.3.x, hitResult.worldTransform.columns.3.y, hitResult.worldTransform.columns.3.z)
let x2 = first!.x
let z2 = -first!.z
let x1 = second!.x
let z1 = -second!.z
let z3 = -third!.z
let m = (z1-z2)/(x1-x2)
var a = atan(m)
if (x1 < 0 && z1 < 0){
a = a + (Float.pi*2)
}else if(x1 > 0 && z1 < 0){
a = a - (Float.pi*2)
}
sceneView.scene.rootNode.addChildNode(yourNode)
let rotate = SCNAction.rotateBy(x: 0, y: CGFloat(a), z: 0, duration: 0.1)
yourNode.runAction(rotate)
yourNode.position = first!
if z3 - z1 < 0{
let rotate = SCNAction.rotateBy(x: 0, y: CGFloat.pi, z: 0, duration: 0.1)
yourNode.runAction(rotate)
}
}
}
}
Theory is:
Make three dots A,B,C such that AB is perpendicular to AC. Tap dots in order A-B-C.
Find angle of AB in x=0 of ARSceneView which gives required rotation for node.
Any one of the point can be refrenced to calculate position to place node.
From C find if node needs to be flipped.
I am still working on some exceptions that needs to be satisfied.
At the moment both ARKit 3.0 and ARCore 1.12 have all necessary API tools to fulfil almost any marker-based tasks for a precise positioning of 3D model.
ARKit
Right out-of-the-box, ARKit has the ability to detect 3D objects and place ARObjectAnchors in a scene as well as to detect images and use ARImageAnchors for accurate positioning. Main ARWorldTrackingConfiguration() class includes both instance properties – .detectionImages and .detectionObjects. It's not superfluous to say that ARKit primordially has indispensable built-in features from several frameworks:
CoreMotion
SceneKit
SpriteKit
UIKit
CoreML
Metal
AVFoundation
In addition to the above, ARKit 3.0 has tight integration with a brand-new RealityKit module helping to implement multiuser connectivity, list of ARAnchors and shared sessions.
ARCore
Although ARCore has a feature called Augmented Images, the framework has no built-in machine learning algorithms, helping us detect real-environment 3D objects, but Google ML Kit framework does have. So, as an Android developer you can use both frameworks at the same time to precisely auto-composite 3D model over a real object in AR scene.
It is worth recognizing that ARKit 3.0 has a more robust and advanced toolkit than ARCore 1.12.
Related
I am trying to make a simple simulation where an iiwa arm picks up foam bricks from a tower. However I have been running into issues finding a way to generate multiple bricks and moving them. The block of code below is how I am currently generating this tower, but this results in the bricks being unable to move the Z plane that they are generated on.
sdf = FindResourceOrThrow("drake/examples/manipulation_station/models/061_foam_brick.sdf")
z=0.35
for i in range(2):
planar_joint_frame = plant.AddFrame(FixedOffsetFrame("planar_joint_frame", plant.world_frame(), RigidTransform(RotationMatrix.MakeZRotation(np.pi/2),[-0.4, 0.2, z])))
instance = parser.AddModelFromFile(sdf, f"object{i}")
plant.AddJoint(PlanarJoint(f"joint{i}", planar_joint_frame, plant.GetFrameByName("base_link", instance), damping=[0,0,0]))
z+=0.05
Is there another way to generate multiple models that can be manipulated by the iiwa arm?
If you want them free to move in 3D, then you don't want to add the planar joint. In fact, you don't need any joint (for them to be free). You probably want something as simple as
for i in range(2):
instance = parser.AddModelFromFile(sdf, f"object{i}")
??
I am programming an iOS app which reads the data from magnetometer. When I run the app on two iPhones, they are creating strange data.
(All data are in [x, y, z] notation) An iPhone 5S creates about [100, 10, -100] and another iPhone 6S creates about [150, 225, -700]. The values shift about 10% when reading multiple times and holding the phone still, and they change little when I turn them.
However, the real magnetic field should be about [0, -30, -30] (measured by an app)
Why am I getting these strange data? (I also measured data from accelerometer, and the data are correct)
Here is my project's source code: https://github.com/lxylxy123456/FGFS-Controller/
What I did is basically like this
let motionManager = CMMotionManager()
motionManager.startMagnetometerUpdates()
if let magnetometerData = motionManager.magnetometerData {
mx = magnetometerData.magneticField.x
my = magnetometerData.magneticField.y
mz = magnetometerData.magneticField.z
}
Mx.text = Float(mx).description
My.text = Float(my).description
Mz.text = Float(mz).description
The magnetometerData is raw data, uncalibrated for internal bias as well as externalities (aka metal), and is essentially meaningless. There is no merit in using the raw data. There is basically never a reason to use these values.
Use the CMDeviceMotion's magneticField at the very least. Even better, ask for information that is germane to your real needs. If you want to know the device's heading, ask for that. If you want to know the device's orientation with reference to magnetic north, ask for that.
I'm using OpenEars in my app for performing the recognition of some words and sentences. I have followed the basic tutorial for the offline speech recognition and executed a porting in Swift. This is the setup procedure
self.openEarsEventsObserver = OEEventsObserver()
self.openEarsEventsObserver.delegate = self
let lmGenerator: OELanguageModelGenerator = OELanguageModelGenerator()
addWords()
let name = "LanguageModelFileStarSaver"
lmGenerator.generateLanguageModelFromArray(words, withFilesNamed: name, forAcousticModelAtPath: OEAcousticModel.pathToModel("AcousticModelEnglish"))
lmPath = lmGenerator.pathToSuccessfullyGeneratedLanguageModelWithRequestedName(name)
dicPath = lmGenerator.pathToSuccessfullyGeneratedDictionaryWithRequestedName(name)
The recognition works well in a quiet room for both single words and whole sentences ( I would say it has a 90% hit rate). However, when I tried in quiet pub with a light background noise the app had serious difficulties in recognising even just word.
Is there any way to improve the speech recognition when there is background noise?
If the background noise is more or less uniform (i.e. has a regular pattern), you can try adaptation of the acoustic model, otherwise it's an open problem sometimes referred to as the cocktail party effect, which can be part solved using DNNs.
Try this setting, works well for me.
try? OEPocketsphinxController.sharedInstance().setActive(true)
OEPocketsphinxController.sharedInstance().secondsOfSilenceToDetect = 2
OEPocketsphinxController.sharedInstance().setSecondsOfSilence()
OEPocketsphinxController.sharedInstance().vadThreshold = 3.5
OEPocketsphinxController.sharedInstance().removingNoise = true
Or You can try iSphinx library.
I'm looking at this
https://developer.apple.com/library/mac/documentation/SceneKit/Reference/SceneKit_Functions/index.html
Aren't basic operations supported?
var t:SCNVector3 = SCNVector3(x: 0,y: -1,z: 2)
var a:SCNVector3 = SCNVector3(x: 1,y: -2,z: -2)
var b:SCNVector3 = t + a
or do I need to create my own operations C-style?
Where are the math vector/matrix functions like transpose? inverse? add? blas? lapack functions?
Accelerate framework doesn't look compatible??
https://developer.apple.com/library/ios/documentation/Accelerate/Reference/BLAS_Ref/index.html#//apple_ref/doc/uid/TP30000414-SW9
I didn't find any official apple simd extensions for swift. I did find this on git hub https://github.com/noxytrux/SwiftGeom
You don't want to use tiny vectors like this with Accelerate framework, with the possible exception of vMathLib. You will lose your performance in overhead to check to see if the arrays and aligned and whether the problem is large enough to multithread.
Much of the SIMD level stuff you are looking for is in simd/simd.h and associated headers.
Also, Swift doesn't support SIMD vectors at the moment.
In Swift 2 (currently part of the Xcode 7 beta), Swift includes the vector and matrix types from the SIMD library. The interface is, for better or for worse, pretty much the same as the C version, but with better support for operators (i.e. you can use * instead of calling matrix_multiply, etc).
Types and functions from the SIMD library aren't in Swift 1.x, but in Xcode 6.3, the GLKit Math library is (at least somewhat) accessible from Swift 1.2. So, you can use, for example, SCNVector3ToGLKVector3 to convert to a GLK value, then use GLK math functions to do things like cross or project.
Note there isn't a builtin function to convert SCNMatrix4 to/from GLKMatrix4, but it's not too hard to write your own.
There are now initialisers to convert e.g. SCNVector3 to simd_float3 and vice versa, then you can use simd operations:
let v1 = simd_float3(SCNVector3(x: 1.0, y: 2.0, z: 3.0))
let v2 = simd_float3(SCNVector3(x: 2.0, y: 3.0, z: 4.0))
let cross = simd_cross(v1, v2)
As of iOS 11 and macOS 10.13, there are SIMD accessors and functions for reading, setting, and transforming the various node properties and scene transforms. #Russ's answer gives an example, but you could also extract node positions directly, with something like:
let t = nodeT.simdPosition
let a = nodeA.simdPosition
let b = simdCross(t, a)
or even
let b = simdCross(nodeT.simdPosition, nodeA.simdPosition)
I am working on an image manipulation problem. I have an overhead projector that projects onto a screen, and I have a camera that takes pictures of that. I can establish a 1:1 correspondence between a subset of projector coordinates and a subset of camera pixels by projecting dots on the screen and finding the centers of mass of the resulting regions on the camera. I thus have a map
proj_x, proj_y <--> cam_x, cam_y for scattered point pairs
My original plan was to regularize this map using the Mathscript function griddata. This would work fine in MATLAB, as follows
[pgridx, pgridy] = meshgrid(allprojxpts, allprojypts)
fitcx = griddata (proj_x, proj_y, cam_x, pgridx, pgridy);
fitcy = griddata (proj_x, proj_y, cam_y, pgridx, pgridy);
and the reverse for the camera to projector mapping
Unfortunately, this code causes Labview to run out of memory on the meshgrid step (the camera is 5 megapixels, which apparently is too much for labview to handle)
I then started looking through openCV, and found the cvRemap function. Unfortunately, this function takes as its starting point a regularized pixel-pixel map like the one I was trying to generate above. However, it made me hope that functions for creating such a map might be available in openCV. I couldn't find it in the openCV 1.0 API (I am stuck with 1.0 for legacy reasons), but I was hoping it's there or that someone has an easy trick.
So my question is one of the following
1) How can I interpolate from scattered points to a grid in openCV; (i.e., given z = f(x,y) for scattered values of x and y, how to fill an image with f(im_x, im_y) ?
2) How can I perform an image transform that maps image 1 to image 2, given that I know a scattered mapping of points in coordinate system 1 to coordinate system 2. This could be implemented either in Labview or OpenCV.
Note: I am tagging this post delaunay, because that's one method of doing a scattered interpolation, but the better tag would be "scattered interpolation"
So this ends up being a specific fix for bugs in Labview 8.5. Nevertheless, since they're poorly documented, and I've spent a day of pain on them, I figure I'll post them so someone else googling this problem will come across it.
1) Meshgrid bombs. Don't know when this was fixed, definitely a bug in 8.5. Solution: use the meshgrid-like function on the interpolation&extrapolation pallet instead. Or upgrade to LV2009 which apparently works (thanks Underflow)
2) Griddata is defective in 8.5. This is badly documented. The 8.6 upgrade notes say that a problem with griddata and the "cubic" setting, but it is fact also a problem with the DEFAULT LINEAR setting. Solutions in descending order of kludginess: 1) pass 'v4' flag, which does some kind of spline interpolation, but does not have bugs. 2) upgrade to at least version 8.6. 3) Beat the ni engineers with reeds until they document bugs properly.
3) I was able to use the openCV remap function to do the actual transformation from one image to another. I tried just using the matlab built in interp2 vi, but it choked on large arrays and gave me out of memory errors. On the other hand, it is fairly straightforward to map an IMAQ image to an IPL image, so this isn't that bad, except for the addition of the outside library.