2 poin oleh GN⁺ 2023-11-28 | 1 komentar | Bagikan ke WhatsApp
  • Setelah putri berusia dua tahun jatuh cinta pada pesawat, dibuatlah Aviator, aplikasi iOS proyek sampingan selama beberapa malam yang menampilkan pesawat di sekitar seperti radar ponsel
  • FlightRadar24 menampilkan posisi pesawat di peta, tetapi pengguna tetap harus menentukan sendiri harus melihat ke arah mana di langit nyata dan pesawat mana yang mudah ditemukan anak
  • Aplikasi ini menggabungkan informasi arah dari Core Location, REST API nonkomersial OpenSky Network, anotasi MapKit, dan UI SwiftUI untuk menampilkan pesawat sesuai arah perangkat
  • Setelah pengujian MVP memastikan pesawat nyata sesuai dengan tampilan aplikasi, ditambahkan penyembunyian peta, pembesaran pesawat beraltitude rendah, animasi radar, efek CRT, suara dan haptic, serta pengaturan warna
  • Aplikasi final dipublikasikan di App Store, dan kandidat peningkatan berikutnya mencakup level zoom, API lanjutan OpenSky, tampilan negara keberangkatan/kedatangan, peningkatan shader Metal, filter jarak/altitude, dan “zany mode”

Dari mengamati pesawat menjadi kebutuhan aplikasi

  • Sang putri menantikan perjalanan dengan pesawat menjelang penerbangan 3 jam saat liburan musim panas ke luar negeri, lalu semakin tergila-gila pada pesawat setelah diajak melihat kokpit oleh awak kabin setelah naik
  • Setelah itu ia sering meminta dicarikan pesawat di langit, bahkan sampai ada momen satu jam di taman, digendong di bahu, untuk mencari pesawat di langit sore
  • FlightRadar24 menampilkan posisi pesawat di atas peta, tetapi pengguna harus mencocokkan sendiri arah mana yang perlu dilihat di langit nyata
  • Di peta 2D, Learjet di ketinggian 40.000 kaki dan AirBus yang baru lepas landas dari London City Airport bisa terlihat mirip, tetapi di langit nyata pesawat besar pada altitude rendah lebih mudah ditemukan
  • Yang dibutuhkan anak dua tahun bukanlah interpretasi peta, melainkan mencari pesawat secara sederhana
  • Masalah awal dirangkum menjadi tiga hal
    • Pencocokan arah: posisi pesawat harus berkorelasi dengan arah langit nyata sesuai arah perangkat
    • Representasi ukuran: ukuran di layar harus berubah sesuai altitude pesawat
    • Kegunaan: aplikasi harus terasa seperti mainan retro, bukan aplikasi pelacakan penerbangan untuk kerja

Desain awal Aviator

  • Ide aplikasinya adalah “menampilkan penerbangan di sekitar pada radar”, dan nama proyek ditetapkan sebagai Aviator
  • Kebutuhan intinya ada tiga
    • Saat perangkat diputar, layar ikut berputar sehingga pesawat ditampilkan pada arah yang benar
    • Ukuran pesawat di layar berubah sesuai altitude
    • Memberi nuansa mainan retro yang seru dan cocok untuk anak
  • Penanganan arah menggunakan pembaruan heading dari Core Location API di iOS
    • Arah perangkat diambil dari didUpdateHeading milik CLLocationManagerDelegate
    • Nilai arah diteruskan ke view SwiftUI dengan CurrentValueSubject dari Combine
  • Data penerbangan menggunakan OpenSky Network
    • REST API sederhana yang menyediakan data penerbangan real-time dalam rentang lintang dan bujur tertentu
    • Gratis untuk penggunaan nonkomersial
    • Rencananya endpoint dipanggil setiap beberapa detik untuk sapuan radar yang realistis
  • Data lokasi diperoleh dari Core Location, lalu rentang lintang dan bujur di sekitar lokasi pengguna di-query
    • Pada gagasan awal, lokasi pengguna akan cukup dikaburkan dengan lintang ±1 derajat dan presisi lokasi 0,1 derajat, sekitar 10 km
    • Pada contoh kode API aktual, digunakan rentang lintang 0,5 derajat dan bujur 1 derajat agar kira-kira berbentuk persegi pada lintang Inggris
  • Karena OpenSky Network API dibatasi untuk penggunaan nonkomersial dan aplikasinya juga bukan layanan komersial, SwiftUI memakai struktur MV sederhana dan hanya layanan inti seperti API serta Location yang dipisahkan

PoC: verifikasi arah, data penerbangan, dan peta

  • PoC arah menangani permintaan izin lokasi, konfigurasi delegate, dan memulai pembaruan heading lewat singleton LocationManager
  • View SwiftUI berlangganan rotationAngleSubject dengan .onReceive, lalu menempatkan persegi-persegi dalam lingkaran untuk membuat efek berputar seperti kompas
  • Pada perangkat uji, respons terhadap perubahan lokasi nyata berjalan baik, tetapi karena animasi memperlakukan 0 derajat dan 360 derajat sebagai nilai terpisah, muncul glitch visual berupa persegi yang berputar satu putaran penuh saat melewati utara sejati
  • OpenSky REST API mengembalikan array penerbangan lokal lewat permintaan GET dengan rentang lintang dan bujur
    • Contoh endpoint memakai states/all dengan parameter lamin, lamax, lomin, lomax
    • Dokumentasi REST API sudah baik, tetapi responsnya berupa struktur tanpa key sehingga field JSON harus di-parse berdasarkan urutan
    • Dengan UnkeyedContainer di Swift, icao24, callsign, origin_country, time_position, last_contact, longitude, latitude, dan lainnya di-decode
  • Percobaan pertama menggambar pesawat dilakukan dengan mengalikan selisih lintang/bujur antara lokasi pengguna dan pesawat dengan skala layar tetap, lalu menempatkan gambar SF Symbol airplane
    • Jarak nyata 1 derajat lintang/bujur berbeda-beda tergantung lokasi, sehingga tidak bisa akurat
    • Meski begitu, ini berguna sebagai titik awal
  • Untuk memverifikasi akurasi, SwiftUI Map diletakkan sebagai latar belakang, lalu pesawat dan kompas ditumpuk di atasnya
    • Dibandingkan proyeksi FlightRadar, jumlah pesawat dan klaster kira-kira cocok, tetapi posisinya cukup meleset
    • Setelah itu pendekatannya diubah menjadi menggambar pesawat langsung sebagai anotasi (annotation) di atas peta

MVP: anotasi MapKit dan uji pengguna

  • Dengan menargetkan iOS 17, fitur anotasi peta MapKit digunakan untuk menampilkan marker berbentuk pesawat pada koordinat geografis nyata
  • FlightMapView menggambar anotasi pesawat di atas Map(position:), lalu menonaktifkan interaksi peta dengan .allowsHitTesting(false) agar sesuai untuk penggunaan sebagai radar
  • Penyesuaian ukuran berbasis altitude pada awalnya menerapkan skala log agar pesawat yang tinggi terlihat lebih besar
    • true_track pesawat dan arah pengguna dari Core Location digabungkan untuk menyelaraskan arah ikon pesawat
  • Pada uji pengguna MVP pertama, sang putri benar-benar menemukan pesawat, dan dipastikan pesawat yang tampil di aplikasi juga terlihat di langit nyata
  • Setelah pengujian, muncul dua hal yang perlu diperbaiki
    • Penyesuaian ukurannya terbalik: untuk menunjukkan pesawat yang mudah ditemukan dengan mata di langit, pesawat pada altitude rendah harus lebih besar
    • Sang putri hanya menginginkan pesawat, bukan peta, sehingga peta perlu dihapus untuk mengurangi noise
  • Rumus skala yang diperbaiki adalah min(2, max(4.7 - log10(flight.geo_altitude + 1), 0.7))
    • Pada pemindaian langit lokal, nilainya berkisar dari 0,7 hingga 2,0, dan distribusi di layar terasa pas

Membuat UI radar

  • OpenSky API kadang mengembalikan timeout, 502 Bad Gateway, dan respons 200 berisi data null
    • Karena ini API nonkomersial gratis tanpa SLA, ditambahkan logika retry dasar di sisi klien
    • Keesokan harinya API berjalan baik sepanjang hari, dan secara umum tampak cukup baik di luar jam-jam traffic tinggi tertentu
  • Untuk membuat peta tidak terlihat, digunakan overlay MapPolygon
    • Walau aslinya overlay ini untuk menyorot area peta, di sini dimanfaatkan untuk menutupi peta dan menyisakan hanya anotasi pesawat
    • Overlay Apple digambar di atas peta dan di bawah anotasi, sehingga hasilnya sesuai keinginan
  • Layar radar diimplementasikan dengan garis, lingkaran konsentris, dan angular gradient berputar selebar 20 derajat
  • Setelah itu efek garis radar disederhanakan menjadi angular gradient 360 derajat
    • Gradient dari hijau ke transparan lalu hitam diputar agar tampak seperti sapuan dan jejak sisa
    • Dinilai bahwa pendekatan “grug-brained” sering kali lebih cocok
  • Saat perangkat diputar cepat, ada artefak visual berupa potongan peta yang terlihat di sudut layar, dan ini diselesaikan dengan reverse mask yang menutupi bagian luar view radar dengan warna hitam

Produksi: efek CRT, suara, pengaturan, App Store

  • Untuk nuansa mainan retro, ditambahkan efek layar CRT
    • Memakai dukungan shader Metal bawaan pada colorEffect di iOS 17
    • Shader menerapkan nilai scanline pada piksel yang bukan hitam
    • Parameter time dimasukkan agar scanline bergerak cepat ke atas dan memberi kesan dinamis
  • Untuk memastikan apakah pendaftaran di App Store diperbolehkan menurut kebijakan OpenSky Network, dikirimkan pertanyaan dan balasan diterima dalam 20 menit
  • Demi pengalaman radar dan aksesibilitas, suara sistem dan haptic ditambahkan saat pembaruan penerbangan
    • AudioServicesPlaySystemSound(1052) digunakan untuk menghasilkan bunyi beep-boop
    • sensoryFeedback(.levelChange, trigger:) milik SwiftUI digunakan
  • Karena suara bisa mengganggu, pengaturan berbasis @AppStorage ditambahkan
    • silent: mode senyap
    • showMap: mematikan overlay radar sehingga peta di bawahnya bisa dilihat
    • userColor: memilih warna radar dengan color picker SwiftUI
  • Karena langganan Midjourney sudah dihentikan, generator gratis nonkomersial dari Gencraft digunakan untuk membuat maskot Aviator yang terasa seperti sang putri memakai topi penerbang
  • Saat bergabung kembali dengan Apple Developer Program, dibayar £79 dan distribusi App Store disiapkan
    • Meski hanya menargetkan iOS 17, screenshot iPhone 6,5 inci dan 5,5 inci tetap harus diserahkan
    • Karena iPhone 5,5 inci terbaru, iPhone 8 Plus, maksimal hanya mendukung iOS 16, AppScreens digunakan untuk mengekspor screenshot dalam dua ukuran
  • Aplikasi sudah tersedia di App Store, dan tautan unduhnya adalah Aviator — Radar on your Phone

Kandidat versi berikutnya

  • Hasil proyek sampingan yang dibuat selama beberapa malam ini terasa memuaskan, dan pengalaman coding membuat mainan untuk sang putri menjadi yang paling menyenangkan setelah sekian lama
  • Kandidat fitur untuk rilis berikutnya adalah sebagai berikut
    • Menambahkan level zoom peta agar radar dibatasi pada pesawat yang lebih dekat saja
    • Menampilkan helikopter, satelit, dan kelas ukuran pesawat dengan API lanjutan OpenSky Network
    • Menambahkan toggle untuk menampilkan negara keberangkatan dan kedatangan pada pesawat
    • Memperbaiki efek layar CRT dengan shader Metal yang lebih canggih
    • Me-refactor kontrol menjadi modal pull-out progressive-disclosure yang ukurannya bisa diubah
    • Mengimplementasikan filter slider jarak dan altitude untuk menyembunyikan pesawat yang rendah tetapi jauh, dan sebagainya
    • Mengimplementasikan zany mode yang merender UFO, serangga raksasa, dan alien di radar

1 komentar

 
GN⁺ 2023-11-28
Pendapat Hacker News
  • Karya yang keren dan tulisannya juga bagus. Menarik melihat betapa kuatnya desain tampilan radar asli “menahan” proyek ini
    Anak itu mungkin tidak akan pernah menyentuh ASR-9 dengan tampilan PPI, apalagi CRT sungguhan, tetapi cukup banyak usaha dicurahkan untuk menyimulasikannya
    Mungkin karena menyukai skeuomorphism, tetapi tampaknya juga karena layar radar asli dengan sangat baik merangkum pertanyaan “apakah ada sesuatu di langit, dan di mana posisinya relatif terhadap saya?”
    UI untuk mengamati langit saat ini terasa bergerak ke arah informasi konteks, tautan ke layanan eksternal, dan ruang iklan, sehingga kehilangan kemampuan untuk menjawab pertanyaan ini dengan mudah

    • Saya suka bahwa layar RADAR adalah hasil dari teknologi yang melahirkannya, yaitu sweep, sekaligus merupakan representasi yang disengaja untuk menampilkan objek pengamatan dengan jelas
      Jarak target dinyatakan sebagai jarak dari pusat, dan azimut sebagai sudut di keliling lingkaran
      Namun bagian yang meniru sweep mungkin bisa dipertanyakan sebagai pilihan desain, sementara warna cerah dan latar tanpa peta membuat layar fokus pada maksudnya, jadi tampaknya sama sekali tidak bermasalah
      Terlihat juga bahwa fitur pelacakan kompas saat memutar ponsel mematahkan ilusi sweep
    • Tidak semua UI pengamatan langit bergerak ke arah seperti itu. SkyMap juga layak dilihat
      https://github.com/sky-map-team/stardroid
    • Salah satu layanan yang masih menangkap dengan baik “apakah ada sesuatu di langit, dan di mana posisinya relatif terhadap saya?” adalah mode AR FlightRadar24
      Saya memahami semua elemen teknologi terkait dan juga mengoperasikan stasiun ADSB sendiri, tetapi tetap saja menakjubkan ketika metadata pesawat dalam bidang pandang muncul saat kamera diarahkan ke langit
    • Sepertinya bagus karena titik awalnya sangat murni. Dimulai dari “ke arah mana harus melihat untuk menemukan pesawat?” lalu dibangun dari sana
  • Luar biasa. Saya masukkan ke daftar hal yang suatu hari ingin dibuat
    Mirip dengan itu, saya membuat logbook penerbangan untuk putra saya yang berusia 5 tahun, dan memulainya sejak ia masih bayi. Setiap kali terbang, saya memintanya bertanya kepada awak kabin apakah kapten bisa menuliskannya
    Kami mencatat rute, tipe pesawat, dan hal-hal yang terjadi, dan para awak kabin benar-benar menyukai hal semacam ini. Kami juga pernah diajak melihat kokpit dan area istirahat awak, dan pesan-pesan yang mereka tulis selalu hangat
    Setiap kali logbook itu dikembalikan, anak saya tersenyum lebar, jadi sangat saya rekomendasikan untuk penggemar pesawat cilik

    • Ayah saya memulai logbook ketika saya masih balita, dan saya masih terus memperbaruinya sekarang di usia 30-an. Semua penerbangan yang pernah saya naiki tercatat di sana, jadi ini benar-benar ide yang luar biasa
    • Satu suara untuk logbook. Saat putri saya berusia sekitar 8 minggu, kami terbang London - New York, dan bahkan punya foto keren dirinya memakai topi kapten di kokpit
    • Jenius. Bahkan sebagai orang dewasa, undangan ke kokpit itu sangat keren, jadi saya pasti akan memulainya pada penerbangan berikutnya
  • Saya suka bahwa mengubah warna tampilan masuk sebagai fitur wajib pada rilis awal. Itu berarti pemahaman terhadap kebutuhan kelompok pengguna targetnya sangat kuat
    Anak 3 tahun pun menyukai mainan apa pun yang punya pemilih warna

    • Saya laki-laki dewasa pun bersemangat kalau ada pemilih warna
      Bayangkan saja kegembiraan tidak rasional saat melewati karma 250 di HN
    • Ini salah satu komponen yang paling diremehkan di SwiftUI
      Bahkan kalau ditunjukkan hari ini, hal pertama yang diperhatikan anak adalah memilih warna, dan itu juga bagus untuk perkembangan motorik halus
  • Bagian “kami terlalu membesar-besarkan perjalanan naik pesawat sampai anak itu terkejut bahwa ia harus naik taksi ke bandara. Ia mengira bisa langsung berjalan dari rumah naik ke pesawat” benar-benar menggemaskan, lucu, sekaligus bisa dimengerti

  • Pada bagian bahwa awak kabin yang melihat anak penggemar pesawat yang lucu akan mengajak melihat kokpit, memakai jumpsuit oranye NASA yang serasi adalah paspor masuk ke semua kokpit
    Para awak kabin lebih bersemangat daripada anak-anaknya, dan anak juga sangat mudah ditemukan di bandara

    • Jenius. Jadi berarti saya atau istri saya tinggal masuk NASA saja. Kira-kira apakah banyak butuh developer iOS di luar angkasa?
  • Tulisan An app can be a home cooked meal, yang mengkloning aplikasi jejaring sosial gagal Tapstack hanya untuk keluarga, juga terkait
    https://www.robinsloan.com/notes/home-cooked-app/

    • Tulisan yang lovely, jadi saya bookmark. Saya setuju bahwa meski unduhannya 0, prosesnya sendiri pasti tetap bermakna
      Tentu saja, menjadi viral juga tidak buruk
  • Ada dua hal kecil yang agak disayangkan
    Setelah titik pesawat digambar lalu bergerak, imersinya sedikit pecah. Akan terasa lebih realistis jika titik itu “dicat” oleh sweep, lalu tetap diam sampai sweep berikutnya
    Untuk lebih realistis lagi, bisa juga mengekstrapolasi dari titik data sebelumnya agar tiap pesawat bergerak secara konsisten pada setiap sweep

    • Keduanya poin yang valid. Jika timing dan sudutnya disesuaikan dengan baik, yang pertama tampaknya cukup mungkin dilakukan
      Yang kedua mungkin malah lebih sederhana. Karena API mengembalikan kecepatan pesawat, perhitungannya bisa dilakukan hanya dengan satu titik data
  • Aktivitas yang bagus dilakukan bersama putri: pergilah ke jalan, area parkir, atau taman yang berada di ujung arah pendaratan landasan bandara internasional terdekat
    Biasanya ini berubah tergantung arah angin, jadi sesuaikan, lalu parkirkan mobil dan tonton pesawat masuk untuk mendarat
    Anak bisa melihat pesawat apa yang datang lewat radar miliknya, dan kami memakai flightradar24
    Anak-anak benar-benar terpukau melihat jet besar yang sedang approach turun begitu dekat ke permukaan tanah, dan ini bisa dinikmati dengan mudah selama berjam-jam. Mereka tidak mau pulang karena ingin melihat apakah pesawat berikutnya lebih besar atau lebih dekat, jadi kami harus bernegosiasi

    • Kalau untuk penulisnya, sepertinya London City Airport (LCY) cocok, dan di sana sudut approach-nya sangat curam
      Hanya pesawat fixed-wing bermesin ganda berukuran Airbus A318 ke bawah yang memiliki sertifikasi khusus untuk pesawat dan awak agar dapat melakukan approach 5,5° yang boleh beroperasi
      https://www.youtube.com/watch?v=yZIDFgpT0-o
      https://en.wikipedia.org/wiki/London_City_Airport
    • Kalau dekat D.C., Gravely Point adalah tempat yang tepat. Baik saat takeoff maupun landing, rasanya seperti bisa menghitung sampai rivet pesawatnya
    • Sebaiknya bawa penyumbat telinga
    • Saat SMA, ada lahan kosong berkerikil tepat di luar pagar bandara di ujung landasan. Kalau arah anginnya pas dan pesawat lepas landas melewati lahan kosong itu, itu jadi tempat yang bagus untuk memarkir mobil dan berkencan
    • Tidak persis sama dengan saran tadi, tetapi di SFO ada Sky Terrace di area sebelum pemeriksaan keamanan untuk menonton pesawat
  • Ada satu masalah dengan aplikasi ini. Di halaman aplikasinya jelas tertulis usia 4+, padahal pengguna sasarannya adalah anak 2 tahun
    Dibuat dengan baik

    • Semoga tetap berada di bawah radar polisi App Store
  • Luar biasa
    Pertanyaan kecil soal detail: apakah scope radar CRT memang benar-benar punya garis sapuan? Saya kira itu display vektor
    Terkait daftar fitur tambahan, karena ini aplikasi untuk mengamati pesawat, sepertinya keren kalau saat mengetuk sebuah titik, jenis pesawatnya ditampilkan selama beberapa detik

    • Benar. Layar radar kuno pada dasarnya seperti osiloskop; posisi X/Y dikendalikan oleh sudut radar dan jarak terkini dari pantulan radar. Semacam plot koordinat polar
      Berkat afterglow fosfor, pantulan radar yang kuat akan tertinggal sebentar di layar. Jika dalam rentang waktu itu radar berputar satu putaran atau lebih, pesawat yang sama akan tampak sebagai titik baru yang sedikit bergeser, yaitu “plot”
      Plot-plot di layar juga bisa ditandai dengan spidol felt-tip untuk dijadikan “track”
      Ada juga layar khusus yang menempatkan kamera film menghadap layar radar untuk merekam pantulan radar selama beberapa jam lalu memutarnya kembali nanti
      Misalnya ada rekaman playback dipercepat pesawat-pesawat Pakta Warsawa pada masa Revolusi Cekoslowakia 1968: https://youtu.be/rAUodXI4LPw?t=622
    • Memang display vektor, tetapi mungkin sedikit berbeda dari yang Anda bayangkan
      Layar radar asli memindai sepanjang arah radial dari pusat ke luar. Timing sapuan sudah ditentukan sebelumnya untuk menskalakan jarak, dan sinyal intensitas beam adalah sinyal pantulan radar yang sudah diperkuat itu sendiri
      Jadi sinyal pantulan yang lebih kuat muncul sebagai “blip” yang lebih terlihat pada layar dengan persistensi panjang
      Bagian menariknya, agar beam radar memindai mengelilingi layar CRT, seluruh rakitan emitter tabung sinar katode digerakkan oleh motor yang tersinkronisasi dengan piringan radar yang berputar
      Rotasi ini harus selalu sesuai dengan kecepatan dan arah piringan radar, kalau tidak blip akan muncul di posisi yang salah
      Garis radial dan garis jarak yang tetap dicetak pada tabung CRT itu sendiri atau pada penutup transparan. Layar seperti ini dipakai selama puluhan tahun, mungkin bahkan sampai 1980-an atau awal 1990-an
      Versi yang lebih baru dapat memindai arah X/Y secara independen dengan rangkaian elektronik sederhana untuk menghindari rakitan emitter beam berputar yang rumit
      Detailnya: https://en.wikipedia.org/wiki/Radar_display#Plan_position_in...
    • Untuk sedikit memperluas poin yang sudah dibahas jawaban lain, beam memang benar-benar memindai secara radial dari pusat ke luar
      Sudutnya bisa dibuat dengan memutar pelat defleksi secara fisik, atau dengan menghitung sin/cos secara elektronik lalu menerapkannya ke pelat defleksi X/Y
      Amplitudo sinyal balik secara langsung menggerakkan arus beam, sehingga target dengan pantulan lebih besar tampak lebih terang
      Ada juga efek storage tube di sini, tetapi cara kerjanya bukan seperti mode bistabil pada display vektor X-Y storage tube komputer awal, melainkan lebih seperti mode persistensi variabel pada sebagian osiloskop
      Karakteristik ini juga memunculkan konsekuensi terkait upaya desain pesawat stealth awal seperti SR-71 atau XB-70
      Pada tabung radar, arus beam diatur agar “blip” menumpuk selama beberapa sweep, dan biasanya blip bergerak kurang dari diameternya sendiri di antara sweep
      Namun jika radar cross-section pesawat pada dasarnya rendah dan pesawatnya sangat cepat sehingga blip bergerak lebih jauh di antara sweep, operator radar dapat menafsirkan blip-blip hantu kecil itu sebagai noise, terutama dalam situasi kacau dengan banyak target