GPS Hardware basics for mobile developers.
4.7 (3)

Click to rate this post!
[Total: 3 Average: 4.7]


Mobile software engineers (iOS and Android), are normally not familiar with how GPS works, instead of just getting Lat/Lon readings, and doing geo operations with it, why not become familiar with how GPS works? πŸ€“

This will not be a lengthy article, it will be a chat between an iOS developer (Alex πŸ‘¨πŸ»β€πŸ’») and an electrical engineer (Sarah πŸ‘©πŸΌβ€πŸ’»).

πŸ‘¨πŸ»β€πŸ’»: So what does GPS stand for?
πŸ‘©πŸΌβ€πŸ’»: It stands for (Global Positioning System).

πŸ‘¨πŸ»β€πŸ’»: Who created it? and what for?
πŸ‘©πŸΌβ€πŸ’»: The GPS project was launched in the USA back in 1973 due to limitations of old navigation systems.

πŸ‘¨πŸ»β€πŸ’»: I know it works without internet, but do I need cellular service to use GPS?
πŸ‘©πŸΌβ€πŸ’»: No.

πŸ‘¨πŸ»β€πŸ’»: How come it works without internet or cellular service?
πŸ‘©πŸΌβ€πŸ’»: You get readings from satellites, there are about 24 artificial satellites in 6 orbits.

πŸ‘¨πŸ»β€πŸ’»: So a mobile needs to connect to all of these?
πŸ‘©πŸΌβ€πŸ’»: Of course not, when you are stationary, you need to be exposed to 3 of them, when you are moving, you will need to be exposed to 4.

GPS Satellites animation (Wikipedia)

πŸ‘¨πŸ»β€πŸ’»: So how come it identifies me? and send me data?
πŸ‘©πŸΌβ€πŸ’»: The Satellites don’t identify you, they only emit synchronous pulses all the time everywhere.

πŸ‘¨πŸ»β€πŸ’»: And how does my mobile give me back the (latitude, longitude, and altitude)?
πŸ‘©πŸΌβ€πŸ’»: It compares the receive time of these pulses from each satellite, and use calculations to determine a point on earth, since the distance between these satellites is constant, and they have atomic clocks, the calculations will not be difficult.

πŸ‘¨πŸ»β€πŸ’»: The service is totally free, and I don’t have any subscription for GPS, how?
πŸ‘©πŸΌβ€πŸ’»: GPS is not the only service for (Global Navigation Satellite Systems), there are many like (GLONASS, BeiDou, Galileo…), there are other commercial solutions that I don’t know much about, there are a lot of details, I heard retail GPS receivers are designed to not work if the tracked object is moving fastly, you get the idea 🧐?
πŸ‘¨πŸ»β€πŸ’»: ah! yes.

BeiDou doesn’t have full earth coverage.


πŸ‘¨πŸ»β€πŸ’»: What is the error margin?
πŸ‘©πŸΌβ€πŸ’»: It’s variable, but you can say between 15 to 50 meters, some commercial systems use other inertial systems to give more accurate estimations.

πŸ‘¨πŸ»β€πŸ’»: What is the minimum detectable value?
πŸ‘©πŸΌβ€πŸ’»: You mean the resolution? theoretically, as far as I know, it’s one inch, but practically it’s about 3 meters.

πŸ‘¨πŸ»β€πŸ’»: I once tried to use the GPS inside a big hospital, it didn’t serve any purpose, the readings were not accurate.
πŸ‘©πŸΌβ€πŸ’»: GPS does not work indoors.
πŸ‘¨πŸ»β€πŸ’»: But I saw some readings on my maps application.
πŸ‘©πŸΌβ€πŸ’»: it’s the last point that was read, some devices like Huawei also augment (Accel/Gyro) sensor data, to mimic a basic INS to give your readings inside buildings, but it’s not reliable.

πŸ‘¨πŸ»β€πŸ’»: And what is used for indoor navigation systems?
πŸ‘©πŸΌβ€πŸ’»: They use beacons and Bluetooth and other technologies, read about apple air tags!

πŸ‘¨πŸ»β€πŸ’»: You mentioned sensors, why can’t we use the basic sensors like accelerometer/gyroscope of the mobile to calculate the position?
πŸ‘©πŸΌβ€πŸ’»: when you “integrate” the acceleration twice, the error will explode fastly, and it will become useless in a short time of movement, even if this works, this will not give you an absolute position, and you have to deal with drifting and gimbal lock and a lot of complexities.

πŸ‘¨πŸ»β€πŸ’»: That was a lot of information, thank you.
πŸ‘©πŸΌβ€πŸ’»: Welcome!, see you soon.









Swift (Set Data-Structure) Basics, With Practical Example : Pizza Cooking
5 (1)

Click to rate this post!
[Total: 1 Average: 5]
Unsplash.com

Swift provides three main collection types, Arrays, Sets, and Dictionaries..

A set is a collection of unique and unordered data, simply, the data elements has no order. and it’s guaranteed to have non-duplicate values.

You use a set instead of an array when you need to test efficiently for membership and you aren’t concerned with the order of the elements in the collection, or when you need to ensure that each element appears only once in a collection.

Swift Source Code.

Asking about the importance of sets is like asking about the importance of the alphabet, set theory is the basic to so much math, any practical application of anything in math is normally an application of set theory.

a Venn diagram, showing the intersection of two sets (Wikipedia)

The basic operations on sets are Union, Intersection, Difference, isSubset, isSuperset.. but swift provide a lot of functions, you can perform set operations with another set, an array, or any other sequence type 🧐, you can use higher order functions like map and filter… etc.

func filter
func isSubset
func isSuperset
func isDisjoint
func subtracting
func isStrictSuperset
func isStrictSubset
func intersection
func map<T>
func dropFirst
func dropLast
func drop
func prefix
func suffix
func split
func firstIndex
func shuffled<T>
func shuffled
func flatMap<ElementOfResult>
func forEach
func first
func withContiguousStorageIfAvailable<R>
func enumerated
func min
func max
func starts<PossiblePrefix>
func elementsEqual<OtherSequence>
func lexicographicallyPrecedes<OtherSequence>
func contains
func allSatisfy
func reduce<Result>
func reversed
func flatMap<SegmentOfResult>
func compactMap<ElementOfResult>
func sorted
func index
func formIndex
func distance
func randomElement<T>
func randomElement
func makeIterator
func isSubset<S>
func isStrictSubset<S>
func isSuperset<S>
func isStrictSuperset<S>
func isDisjoint<S>
func union<S>
func subtracting<S>
func intersection<S>
func symmetricDifference<S>
func hash
func joined
func joined<Separator>
func encode
func mapValues<T>
func compactMapValues<T>
func merging<S>
func merging

let’s start with a simple example

// Data
var myKitchenItemsSet: Set = ["Mozzarella","Mushrooms","Pineapples","Tomatoes","Mushrooms","Garlic"]
let shoppingListItemsSet: Set = ["Olives", "Tomatoes","Sourdough"]
let pizzaIngredientsSet: Set = ["Sourdough","Mozzarella","Mushrooms","Tomatoes","Olives"]

// the order of union operator is not important, even union1 and union2 show up differnlt when printing!
let union1 = myKitchenItemsSet.union(shoppingListItemsSet)
let union2 = shoppingListItemsSet.union(myKitchenItemsSet)

// union1 and union2 show up differently when printed, but keep in mind that they are equal

print("union1",union1)
print("union2",union2)
print("areUnionsEqual",(union1 == union2))

let itemsNeeded = shoppingListItemsSet.subtracting(myKitchenItemsSet)
print("What I need to buy:",itemsNeeded)

// Buy the needed elements
myKitchenItemsSet.formUnion(itemsNeeded)

let canMakePizza = pizzaIngredientsSet.isSubset(of: myKitchenItemsSet)
print("canMakePizza",canMakePizza)

Defining a set is straightforward, you can explicitly define the type to be a Set, notice how you can’t have multiple types directly, you can’t mix integers with strings for example, in the example the type was inferred though.

Next we created two unions to proof that the order of the union has no value, it’s like addition, even though the union sets get printed with random order in the terminal.

Then we used Subtraction to look up the items that we need to have on the shopping list, in other words, remove items already in the kitchen even if they are in the pizza recipe.

We can add the items needed into my kitchen items, notice that how duplicate items are ignored, lastly we check if the kitchen items “has” all the items in the pizza recipe.

Say you want to make a pizza for Justin Bieber?


var pizzaIngredientsForJustinSet: Set = ["Sourdough","Mozzarella","Tomatoes","Olives","Amanita phalloides"]

print("can I make Pizza for the Justin?",pizzaIngredientsForJustinSet.isSubset(of: myKitchenItemsSet))

myKitchenItemsSet.insert("Rotten Mushrooms")
myKitchenItemsSet.insert("Amanita phalloides")

print("can I make Pizza for the Justin Bieber?",pizzaIngredientsForJustinSet.isSubset(of: myKitchenItemsSet))

Yes, this will not work until you add “Amanita phalloides” πŸ‘

Bridging between Set and NSSet

You can bridge between Set and NSSet using the as operator, For bridging to be possible, the Element type of a set must be a class, or a type that bridges to a Foundation type.

Swift Source Code.

Performance

Sets are in general faster to process, but due to their restriction of non-repeated values, and having no order, they are not often used.

Using unicode markers Β (LTR: 0x200E, RTL:200F) to align “hybrid RTL/LTR strings” correctly.
4.5 (2)

Click to rate this post!
[Total: 2 Average: 4.5]
Photo From Unsplash

So you have some text that contains both Arabic and English languages at the same time? and having difficulty aligning it because sometimes it starts with english, and other times it starts with Arabic?

The following example illustrates
– this problem πŸ›
– some hacky way to solve it πŸ‘Ί
– and the correct way to solve it 🧐.

3 example labels

Top line: shows a line that is being rendered incorrectly, because the first word is Arabic, and you are expecting it to show up on the left, but it’s not 🀦🏻.

Middle line: one hacky way to solve this, is to start your text all the time with a LTR word, not the best solution πŸ‘Ί

Bottom line: this is showing up correctly, because it’s adjusted using unicode markers.

Unicode characters set offers two marker characters (LTR: 0x200E, RTL:200F). These are invisible, but control the direction, I just need to add this \u{200E} to force the wrapping direction.

Playground example:

import UIKit
import PlaygroundSupport

extension String {

    func withHighlighted(word: String) -> NSMutableAttributedString {
        let attributes = [
            [NSAttributedString.Key.foregroundColor:UIColor.blue],
            [NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 14)]
        ]
        
        let range = (self as NSString).range(of: word)
        let result = NSMutableAttributedString(string: self)
        for attribute in attributes {
            result.addAttributes(attribute, range: range)
        }
        return result
    }
    
}

class MyViewController : UIViewController {
    
    override func loadView() {
        
        let view = UIView()
        let topLabel = UILabel()
        let middleLabel = UILabel()
        let bottomLabel = UILabel()

        topLabel.frame = CGRect(x: 40, y: 40, width: 300, height: 20)
        middleLabel.frame = CGRect(x: 40, y: 80, width: 300, height: 20)
        bottomLabel.frame = CGRect(x: 40, y: 120, width: 300, height: 20)
        
        let word1 = "ΨΉΨ¨Ψ― Ψ§Ω„Ω„Ω‡"
        let word2 = "added a new comment"
        let adjustor = "\u{200E}"
        
        topLabel.attributedText = "\(word1) \(word2)".withHighlighted(word: word1)
        middleLabel.attributedText = "note: \(word1) \(word2)".withHighlighted(word: word1)
        bottomLabel.attributedText = "\(adjustor) \(word1) \(word2)".withHighlighted(word: word1)
        
        view.addSubview(topLabel)
        view.addSubview(middleLabel)
        view.addSubview(bottomLabel)

        self.view = view
        
    }
    
}

PlaygroundPage.current.liveView = MyViewController()