You are on page 1of 9

LAPORAN

GLOBAL POSITION NETWORK

TRILATERATION

Disusun Oleh :

Cinthya Rizki Aninda (123140110)

PROGRAM STUDI TEKNIK INFORMATIKA

FAKULTAS TEKNIK INDUSTRI

UNIVERSITAS PEMBANGUNAN NASIONAL “VETERAN”

YOGYAKARTA

2019
Program Trilateration

<?php
/*
* This file is part of trilateration package
*
* Copyright (c) 2017 Mika Tuupola
*
* Licensed under the MIT license:
* http://www.opensource.org/licenses/mit-license.php
*
* Project home:
* https://github.com/tuupola/trilateration
*
*/
namespace Tuupola\Trilateration;
use Tuupola\Trilateration;
use Nubs\Vectorix\Vector;

class Sphere extends Point


{
protected $radius;
public function_construct($latitude, $longitude, $radius)
{
$this->latitude = $latitude;
$this->longitude = $longitude;
$this->radius = $radius;
}
public function radius()
{
return $this->radius;
}
public function enlarge($meters)
{
return new Sphere($this->latitude, $this->longitude, $this->radius +
$meters);
}
public function_toString()
{
return "{$this->latitude},{$this->longitude},{$this->radius}";
}
}
Sphare.php

<?php
/*
* This file is part of trilateration package
*
* Copyright (c) 2017 Mika Tuupola
*
* Licensed under the MIT license:
* http://www.opensource.org/licenses/mit-license.php
*
* Project home:
* https://github.com/tuupola/trilateration
*
*/
namespace Tuupola\Trilateration;
Intersection.php
use Nubs\Vectorix\Vector;
use Tuupola\Trilateration\Sphere;
use Tuupola\Trilateration\Point;
use RuntimeException;
class Intersection
{
const EARTH_RADIUS = 6378137;
private $autocorrect = 1;
private $spheres = [];
public function __construct(Sphere ...$spheres)
{
$this->spheres = $spheres;
}
public function addSphere(Sphere $sphere)
{
$spheres = array_merge([$sphere], $this->spheres);
return new self(...$spheres);
}
public function position()
{
$point = $this->intersection();
/* If autocorrect is set increase sphere radius until they intersect.
*/
if ($this->autocorrect) {
while (!$point) {
$this->spheres[0] = $this->spheres[0]->enlarge($this->autocorrect);
$this->spheres[1] = $this->spheres[1]->enlarge($this->autocorrect);
$this->spheres[2] = $this->spheres[2]->enlarge($this->autocorrect);
$point = $this->intersection();
}
}
/* If solution not found throw. */
if (!$point) {
throw new RuntimeException("Spheres do not intersect.");
}

return $point;
}
private function intersection()
{
/* http://en.wikipedia.org/wiki/Trilateration */
$P1 = $this->spheres[0]->toEarthCenteredVector();
$P2 = $this->spheres[1]->toEarthCenteredVector();
$P3 = $this->spheres[2]->toEarthCenteredVector();

/* $ex is the unit vector in the direction from P1 to P2. */


$ex = $P2->subtract($P1)->normalize();
/* $i is the signed magnitude of the x component, in the figure
1 */
/* coordinate system, of the vector from P1 to P3. */
$i = $ex->dotProduct($P3->subtract($P1));
/* $ey is the unit vector in the y direction. Note that the
points P1, P2 */
/* and P3 are all in the z = 0 plane of the figure 1 coordinate
system. */
$temp = $ex->multiplyByScalar($i);
$ey = $P3->subtract($P1)->subtract($temp)->normalize();
/* $ez is third basis vector. */
$ez = $ex->crossProduct($ey);
Intersection.php
/* $d is the distance between the centers P1 and P2. */
$d = $P2->subtract($P1)->length();
/* $j is the signed magnitude of the y component, in the figure
1 */
/* coordinate system, of the vector from P1 to P3. */
$j = $ey->dotProduct($P3->subtract($P1));

$x = (
pow($this->spheres[0]->radius(), 2) –
pow($this->spheres[1]->radius(), 2) +
pow($d, 2)
) / (2 * $d);
$y = ((
pow($this->spheres[0]->radius(), 2) –
pow($this->spheres[2]->radius(), 2) +
pow($i, 2) + pow($j, 2)
) / (2 * $j)) - (($i / $j) * $x);
/* If $z = NaN if circle does not touch sphere. No solution. */
/* If $z = 0 circle touches sphere at exactly one point. */
/* If $z < 0 > z circle touches sphere at two points. */
$z = sqrt(pow($this->spheres[0]->radius(), 2) - pow($x, 2) -
pow($y, 2));
/* Using absolute value makes formula pass even when circles do not
*/
/* overlap. The result, however is not correct. */
//$z = sqrt(abs(pow($this->spheres[0]->radius(), 2) - pow($x, 2) -
pow($y, 2)));
if (is_nan($z)) {
return false;
}
/* triPt is vector with ECEF x,y,z of trilateration point */
$triPt = $P1->add($ex->multiplyByScalar($x)) ->add($ey-
>multiplyByScalar($y)) ->add($ez->multiplyByScalar($z));
$triPtX = $triPt->components()[0];
$triPtY = $triPt->components()[1];
$triPtZ = $triPt->components()[2];
/* Convert back to lat/long from ECEF. Convert to degrees. */
$latitude = rad2deg(asin($triPtZ / self::EARTH_RADIUS));
$longitude = rad2deg(atan2($triPtY, $triPtX));
return new Point($latitude, $longitude);
}
}

Intersection.php

<?php
/*
* This file is part of trilateration package
*
* Copyright © 2017 Mika Tuupola
*
* Licensed under the MIT license:
* http://www.opensource.org/licenses/mit-license.php
*
* Project home:
* https://github.com/tuupola/trilateration
*
*/
namespace Tuupola\Trilateration;
Point.php
use Tuupola\Trilateration;
use Nubs\Vectorix\Vector;
class Point
{
const EARTH_RADIUS = 6378137;
protected $latitude;
protected $longitude;

public function __construct($latitude, $longitude)


{
$this->latitude = $latitude;
$this->longitude = $longitude;
}
public function latitude()
{
return $this->latitude;
}
public function longitude()
{
return $this->longitude;
}
public function toEarthCenteredVector()
{
$vx = self::EARTH_RADIUS * (cos(deg2rad($this->latitude()))
* cos(deg2rad($this->longitude())));
$vy = self::EARTH_RADIUS * (cos(deg2rad($this->latitude()))
* sin(deg2rad($this->longitude())));
$vz = self::EARTH_RADIUS * (sin(deg2rad($this->latitude())));
return new Vector($vx, $vy, $vz);
}
public function distance(Point $point)
{
$lat1 = $this->latitude();
$lon1 = $this->longitude();
$lat2 = $point->latitude();
$lon2 = $point->longitude();
$latd = deg2rad($lat2 - $lat1);
$lond = deg2rad($lon2 - $lon1);
$a = sin($latd / 2) * sin($latd / 2) +
cos(deg2rad($lat1)) * cos(deg2rad($lat2)) *
sin($lond / 2) * sin($lond / 2);
$c = 2 * atan2(sqrt($a), sqrt(1 - $a));
return self::EARTH_RADIUS * $c;
}
public function __toString()
{
return “{$this->latitude},{$this->longitude}”;
}
}

Point.php
<?php
/*
* This file is part of trilateration package
*
* Copyright (c) 2017 Mika Tuupola
*
* Licensed under the MIT license:
* http://www.opensource.org/licenses/mit-license.php
*
* Project home:
* https://github.com/tuupola/trilateration
*
*/
namespace Tuupola\Trilateration;
use Symfony\Component\Process\Process;
use Symfony\Component\Process\Exception\ProcessFailedException;
use Tuupola\Trilateration\Sphere;
use Tuupola\Trilateration\Point;

class NonLinearLeastSquares
{
private $spheres = [];
public function __construct(Sphere ...$spheres)
{
$this->spheres = $spheres;
}
public function addSphere(Sphere $sphere)
{
$spheres = array_merge([$sphere], $this->spheres);
return new self(...$spheres);
}
public function position()
{
$latitude = array_map(function ($sphere) {
return $sphere->latitude();
}, $this->spheres);
$latitude = implode($latitude, ",");
$longitude = array_map(function ($sphere) {
return $sphere->longitude();
}, $this->spheres);
$longitude = implode($longitude, ",");
$distance = array_map(function ($sphere) {
return $sphere->radius();
}, $this->spheres);
$distance = implode($distance, ",");
$r = <<<EOF

# install.packages("geosphere")
library(geosphere)
locations <- data.frame(
latitude = c($latitude),
longitude = c($longitude),
distance = c($distance)
)
EOF;
$r .= <<<'EOF'

NonLinearLeastSquares.php
# Use average as the starting point
fit <- nls(
distance ~ distm(data.frame(longitude, latitude), c(fitLongitude,
fitLatitude)),
data = locations,
start=list(fitLongitude=mean(locations$longitude),
fitLatitude=mean(locations$latitude)),
control=list(maxiter=1000, tol=1e-02, minFactor=1/2048)
)
# Shortcut to result
longitude <- summary(fit)$coefficients[1]
latitude <- summary(fit)$coefficients[2]
print(paste(latitude, longitude, sep=","))
EOF;
/* TODO: Probably should check /opt and other paths too. */
$binary = "/usr/local/bin/R";
if (!file_exists($binary)) {
$binary = "/usr/bin/R";
}
$process = new Process("$binary --slave --vanilla");
$process->setInput($r);
$process->run();
if (!$process->isSuccessful()) {
throw new ProcessFailedException($process);
}
$output = $process->getOutput();
$output = str_replace('"', "", $output);
$output = str_replace("[1] ", "", $output);
list($latitude, $longitude) = explode(",", $output);
return new Point($latitude, $longitude);
}
}

NonLinearLeastSquares.php
Pembahasan
Pada program trilateration di atas terdiri dari empat file php yang sudah dicoba
dieksekusi melalui website github yang menyediakan sourcecode tersebut. File pertama adalah
Sphare.php yang merupakan turunan dari class Point. Dalam class Sphare tersebut terdapat tiga
variabel yang diolah yaitu latitude, longtitude dan radius. Dimana radius akan berubah ketika
fungsi enlarge dipanggil. Selanjutnya pada class Intersection yang berisi perhitungan mencari
titik perpotongannya. Dengan bantuan rumus yang ada maka dibuatlah variabel-variabel yang
berisi rumus untuk mencari Point perpotongan tiga Sphare tersebut, dengan
mengimplementasikan kalkulasi posisi untuk menemukan perpotongan dengan aljabar. Setelah
diketahui titik perpotongan maka dicarilah radius pada masing-masing titik sphare. Dimana
radius pada tiga sphare tersebut akan membesar dengan menggunakan fungsi enlarge sampai
batas titik pointnya. Serta ketiganya juga membesar bertambah 1 radiusnya dengan autocorrect
sampai mereka berpotongan. Setelah pengolahan selesai di class instersection maka latitude
dan longtitude yang dihasilkan perpotongan tadi dikirim ke class point untuk selanjutnya
dijadikan letak lokasi user tersebut. Setelah proses itu ditemukanlah titik koordinat lokasi dari
ketiga koordinat yang telah diketahui tersebut

You might also like