Before we used gyroscope, acceleration sensor to do some fun effects, today we use the third sensor – magnetometer – to do an AR scene. When it comes to AR, please don’t insult me. It doesn’t use WWDC’s ARKit. And the point of today’s example is to learn how to use magnetometers, which is not intrinsically relevant to AR. A gimmick, just a gimmick…
Magnetometer in front of the accelerometer, gyroscope, are used in the iOS last time said the CoreMotion framework CoreMotion, also use CMMotionManager.
After the completion of the effect, you can see that there will be a background picture of sky and stars moving with the screen below the video output, and the current direction information and geographic information will be printed in the upper left corner of the screen in real time.
1. Introduction of magnetometer
Magnetometer refers to all kinds of instruments used to measure magnetic field, also known as magnetometer, Gauss meter. It can sense the earth’s magnetic field and get directional information.
1.1 Application Scenarios
Obviously, the typical application is for electronic compasses and navigation.
I’ve seen some god use a magnetometer to make flowers and cows fly. The magnetometer, accelerometer and microphone on iPhone are used to track the magnets in plane and 3d, and the feedback can be real-time on the iPhone screen.
It looks like it blew up, doesn’t it? House fat also specifically found the report of this article, interested can go in to have a look, there is the realization of the video. Mobile.163.com/14/1127/09/…
1.2 Basic Concepts to be understood
To use magnetometers, we often hear “magnetic north” and “true north” as two high-frequency words, and CoreMotion will return these two values. What does that mean?
- True North: The geographic North Pole
- Magnetic North: Refers to the North Pole of the magnetic field
What? What the hell is this? Come on, let’s get this straight.
-
Magnetic north magnetic north is based on the magnetotelluric field, and azimuths transmitted through various sensors are based on magnetic north. BUT!!!! Knock on the blackboard !!!!! The exact position of magnetic north changes over time. That is to say, with the rotation of the earth, we have in addition to the change of the year, the change of time, even the magnetic field will change. Well, that’s right.
-
True north changes due to magnetic north, so how do we use it? It is impossible to calculate the earth’s axis of rotation and consider time. Hence the concept of true North.
True North is the geographic North Pole of the earth’s rotation, which is a fixed position considering all factors. So when we refer to the north of the electronic compass, we mean the true north. In general, the orientation needs to be corrected to true north. Apple is very sweet ah, true north do not have to calculate their own, direct will also return the value.
The remaining concepts are magnetic deflection correction, network north, network north correction, convergence Angle and so on.
Isn’t the north on the electronic compass inconsistent with the north on the compass?
The child who asked that question was very clever. It must be inconsistent. But the error is within the limits of sensory acceptance. In our example, let’s print out both values and see for ourselves.
2. Use of magnetometers
2.1 Procedure
Magnetometers are also managed through the CoreMotion framework, so as with the previous two sensors, there are four standard steps:
- Initialize the CMMotionManager managed object.
- Call the object method of the managed object to get the data;
- Processing data;
- Stop fetching data when it is no longer needed.
2.2 Two methods of magnetometer data acquisition
There are two ways to get data in CoreMotion, one called PUSH and one called PULL. As the name implies, PUSH is passive acquisition. Once set, the thread periodically pushes the data back. It is conceivable that the consumption of resources will be slightly greater. PULL is to take. You have to pull it to get the data. Don’t refuse. Last time the code was Swift, this time we will use OC.
2.2.1 Method of PULL
//PULL method to get data - (void)pullMagnetometer {// Determine whether the magnetometer is availableif(self, manager magnetometerAvailable) {/ / set the magnetometer sampling frequency self. Manager. MagnetometerUpdateInterval = 0.1; // Update starts, background thread starts running. This is Pull. [self.manager startMagnetometerUpdates]; NSLog(@"X = %f,Y = %f,Z = %f",self.manager.magnetometerData.magneticField.x,self.manager.magnetometerData.magneticField.y,self.manager.magnetometerDa ta.magneticField.z); }else {
NSLog(@"It cannot be used!"); }}Copy the code
2.2.2 PUSH Mode
(void)pushMagnetometer {// Check whether the magnetometer is availableif(self, manager magnetometerAvailable) {/ / set the magnetometer sampling frequency self. Manager. MagnetometerUpdateInterval = 0.1; // Get and process data in Push mode, here we just do simple printing again. Put the sampling work in the main thread. [self.manager startMagnetometerUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:^(CMMagnetometerData * _Nullable magnetometerData, NSError * _Nullable error) { NSLog(@"X = %f,Y = %f,Z = %f",magnetometerData.magneticField.x,magnetometerData.magneticField.y,magnetometerData.magneticField.z);
}];
} else {
NSLog(@"It cannot be used!"); }}Copy the code
3. Start our short case
When writing this case, we found that to achieve a realistic AR, we did not share a lot of things. So after writing the example, I made some adjustments to this example when WRITING this article. A lot of simplification cuts a lot of requirements. However, the final use of the camera, Baidu map, if these two are not, it really can not be regarded as AR.
After the completion of the effect, you can see that there will be a background picture of sky and stars moving with the screen below the video output, and the current direction information and geographic information will be printed in the upper left corner of the screen in real time.
Don’t be nervous about the camera in the case, we will share it later. There’s one more thing that I mentioned before, that multithreading remembers, and I’ll fill it up in the next series.
3.1 Mind mapping
3.2 Preparations
3.2.1 SDK import
In this example, we use Baidu Map, so we need to import baidu map SDK. Because we have not shared how to use the third-party library, you can have a look at this article iOS· Use the third party (Baidu Map SDK) to achieve positioning and other functions development
3.2.2 Request for camera and positioning permission
IPhone has strict regulations on the privacy rights of APP users. Each APP must let users know and agree before using users’ privacy. Maybe that’s why Ben loves the iPhone so much. Although there are many problems when developing, at least the product is always in the perspective of the user.
Ask the user for access to camera and location information in info.plist.
- Privacy – Camera Usage Description
- Privacy – Location When In Use Usage Description
3.2.3 Camera use
The camera, in this case, uses the AVFoundation framework. It is also very sad that I have not shared this part before. So if you can’t wait for me to share, check this out first. Objc # 21: Camera Capture on iOS
Don’t forget in the header file < AVFoundation/AVFoundation. H >, at the same time observe AVCaptureVideoDataOutputSampleBufferDelegate agency agreement.
3.3 Create a dynamic starry sky background
The sky map I found on the Internet is 4000 by 2800, so make it completely off-screen. In this way, activities can be carried out according to mobile phone movements.
Again, a magnification factor is added after the value obtained from the gyroscope in order to make the effect visible. In this little example we’re using 5.
3.3.1 Use gyroscope for shaking prevention
If the data returned by the gyroscope is within a certain narrow range, we treat it as just hand shaking and do not process the image itself. So you don’t see the background image shaking.
- Note: it is possible for gyroscopes to return negative rotations of each axis, so don’t forget to use absolute values.
// Do anti-jitter processing, if the mobile phone rotation is not too large, do not perform the operationif(Fabs (gyrodata.rotationrate.x) * multiplier < 0.2&& fabs(gyrodata.rotationrate.y) * multiplier < 0.2&1) {return ;
}
Copy the code
3.3.2 Make the background sky map run along with the screen
Simply modify the center of the background image and add the required amount of displacement to the original center. The important thing to note here is that the boundary values need to be handled. If the screen rotates in a messy way, we should always have a background underneath the video output layer.
// The background image is three times the screen width and twice the height. Restrictions are imposed to prevent overstepping boundariesif(imageRotationX > self. View. Frame. The size, width * 1.5) {imageRotationX = self. View. Frame. The size, width * 1.5; }if(imageRotationX < - self. View. Frame. The size. (width * 0.5)) {imageRotationX = (. - self. The view frame. The size. Width * 0.5); }if (imageRotationY > self.view.frame.size.height) {
imageRotationY = self.view.frame.size.height;
}
if (imageRotationY < 0) {
imageRotationY = 0;
}
Copy the code
3.4 Output magnetometer information, latitude, longitude and altitude by using Baidu map
3.4.1 Output magnetometer information
According to the document of Baidu Map SDK, after the user’s direction information changes, the following methods will be called. We didn’t do anything special here, just simply printed out the magnetic north, true north and three axis offsets.
And you’ll see how far apart the magnetic north is from the true north when you run it.
/** * After the user direction is updated, *@param userLocation new userLocation */ - (void)didUpdateUserHeading (BMKUserLocation *)userLocation { self.magnetometerInfo.numberOfLines = 0; self.magnetometerInfo.text = [NSString stringWithFormat:@"Magnetic north: % 0 f the true north: %. 0 f \ n migration: %. 0 f \ nx: %. 1 f y: %. 1 f z: %. 1 f". userLocation.heading.magneticHeading,userLocation.heading.trueHeading,userLocation.heading.headingAccuracy,userLocation. heading.x,userLocation.heading.y,userLocation.heading.z]; }Copy the code
3.4.2 Output user location information: latitude, longitude, and altitude
/** * After user location is updated, Will call this function * @ param userLocation new user location * / - (void) didUpdateBMKUserLocation: (userLocation BMKUserLocation *) { self.physicalLocation.numberOfLines = 0; self.physicalLocation.text = [NSString stringWithFormat:@"Longitude :%f \n Latitude :%f \n Height :%f",userLocation.location.coordinate.longitude,userLocation.location.coordinate.latitude,userLocation.location.altitude];
}
Copy the code
Source code download address: OC download address