# CS + Physics → app studio > Computer science plus physics shaped uranashel — not as credentials, but as a way to ask what sensors mean before writing code. 2025-06-28 · 22 min read · studio, physics · by ntan (ntan) for uranashel Canonical HTML: https://uranashel.com/blog/physics-degree-apps.html --- I studied computer science and physics on separate tracks. CS taught me to ship software before the semester ended; physics taught me what the numbers in a sensor CSV actually mean. uranashel sits at the intersection of those two educations, and nearly every feature that works across our five apps followed the same sequence: a real-world problem appeared, physics described why the naive approach fails, and code was written to respect that description rather than fight it. Nobody at this studio ever sat down and said "AI is hot, let's wrap an API." Every product began as a physical annoyance that happened to one of us personally. The five apps look like separate ideas (parking navigation, sleep audio, a pocket lab, an acoustics toolkit, a save-for-later tool), but four of them are one idea wearing different sensors. Find the physical quantity the phone can actually measure, work out its noise floor, and refuse to display anything the noise cannot support. The rest of this post walks through how that played out app by app, with the numbers behind each decision. ## Wheria: when the map lies The origin story lives in [its own post](https://uranashel.com/blog/building-wheria-indoor.html). The short version is a photo of pillar E9 on floor B2, taken because nothing on my phone could remember where the car was. GPS fails underground for reasons no map vendor can patch: L-band microwave signals attenuate badly in reinforced concrete, and the reflections that do arrive have travelled longer paths than the straight line, so multipath biases pseudorange estimates by tens of meters. The naive software response is to show the blue dot anyway, maybe smooth it a little. That is lying to the user with extra steps. The physics-informed response is pedestrian dead reckoning. Steps come from accelerometer peaks. For heading, integrate the gyro and correct it with the magnetometer whenever the field looks clean. The barometer supplies floor hints, and a Kalman filter fuses everything into a position that carries its own uncertainty instead of false precision. The full pipeline is in the [Kalman post](https://uranashel.com/blog/kalman-filter-parking.html), and the step detector has [its own writeup](https://uranashel.com/blog/step-detection-imu.html). I would not have written any of it without knowing why double integration of accelerometer data drifts meters per second, or why compass readings become worthless near steel columns. CS alone would have produced a prettier map tile. Physics alone would never have made it through App Store review. ## The arithmetic of drift The drift claim deserves numbers, because that one fact shapes the entire Wheria architecture. A phone accelerometer carries a residual bias `b` on the order of 0.03 m/s² even after calibration. Integrate twice and position error grows as `x_err(t) = ½·b·t²`. At t = 60 s that is 0.5 · 0.03 · 3600 = 54 m. Walk for one minute and the naive dot sits two garage aisles away from you. Step counting sidesteps the whole mechanism: a step is a detected event, stride length is bounded by human biomechanics, and error grows linearly with distance walked at roughly 2%. The quadratic term never gets a chance to exist. The barometer earns its seat by the same logic. Near sea level, pressure falls about 12 Pa per metre of altitude, from `Δh = ΔP/(ρg)` with ρ ≈ 1.2 kg/m³ and g = 9.81 m/s². The garages we measure have floors 3.2 m apart, so one floor is a step of roughly 38 Pa. Phone barometer noise sits at 0.3–1 Pa RMS (bench note: 4 phones on a shelf for 48 h, logged at 1 Hz, 10-sample median filter). A floor change therefore stands about 40 σ clear of the noise even on our worst unit. Weather is the real enemy; a front can move absolute pressure by more than a floor's worth in an hour, so the detector only looks at short-window differences and re-anchors after every confirmed change. ``` // floor hint from barometer, evaluated at 1 Hz p = median(last 10 samples) // kills the 0.3–1 Pa RMS noise dp = p - p_ref // Pa, relative to last confirmed floor dh = dp / 12.0 // metres, ~12 Pa per metre if abs(dh) > 2.4 { // 75% of a 3.2 m floor floors = round(dh / 3.2) emitFloorHint(floors) p_ref = p // re-anchor; weather drift dies here } ``` The full derivation, hysteresis and all, is in the [barometer math post](https://uranashel.com/blog/barometer-parking-math.html). ## Sonarish: when the machine hums differently Sonarish started because an air conditioner began humming at 127 Hz after three years of service — a harmonic of mains frequency and motor pole count. Rotating machinery has a vocabulary: shaft frequency at `f_shaft = RPM/60`, bearing defect sidebands spaced around it, broadband noise from loose mounts. The tempting shortcut is a cloud-trained AI classifier. What shipped instead is an on-device FFT with A-weighted LAeq integration, a baseline snapshot taken while the machine is healthy, and a diff view showing which frequency bins rose more than 6 dB since last month. We deliberately do not auto-diagnose bearing failures. A failing bearing's spectrum depends on ball count, race diameters and shaft speed; without the nameplate the physics is ambiguous, so the app shows the spectrum diff and you call a technician with data instead of vibes. Every choice upstream of that screen is physics too. Nyquist's theorem, `f_s ≥ 2·f_max`, sat behind picking the 48 kHz sample rate. A-weighting (the reason a 100 Hz hum reads about 19 dB lower than it measures) sat behind making readings comparable to a municipal noise ordinance and to the NIOSH 8-hour limit of 85 dB(A). Get either wrong and the app becomes confidently misleading. Bench note from our own log: one AC unit, one 60 s clip every Monday for 14 months from the same tripod position; the 127 Hz bin ended 8 dB above its healthy baseline. The [baseline post](https://uranashel.com/blog/machine-fault-baseline.html) and the [A-weighting post](https://uranashel.com/blog/a-weighting-decibels.html) go deeper on both halves. ## Estua and Phyzix: perception and pedagogy Estua exists because the human auditory system detects periodicity in looped recordings within minutes — a psychoacoustics problem, not a compression problem. The fix is real-time synthesis: 1/f noise shaped by uncorrelated LFO modulation, generated fresh forever, so there is no loop point for the ear to find. That synthesis runs on the audio thread under hard real-time rules (no malloc, no locks, every 48 kHz buffer delivered on deadline), documented in the [audio thread post](https://uranashel.com/blog/dsp-audio-thread.html). Miss one deadline and the person you are easing into sleep hears a click. The other end of the pipeline is delicate too: [Sonarish's breathing sonar](https://uranashel.com/blog/sonar-breathing-doppler.html) resolves chest displacement of 118 µm, which is the scale of signal in play when the goal is keeping someone asleep. Phyzix approaches from the opposite direction. Students treat phones as consumption devices, while the same hardware carries an accelerometer, gyroscope, magnetometer, barometer and microphone that a 1990s university lab would have envied. Phyzix draws live sensor graphs with SI units, exports CSV, and places each simulation's equation beside its animation so the link between formula and motion stays visible on one screen. Neither app required a physics degree to conceive. Both required physics to implement correctly — psychoacoustic masking for one, sampling and unit discipline for the other. The [pocket lab post](https://uranashel.com/blog/phyzix-pocket-lab.html) has the full tour. ## What each discipline alone would miss Computer science without physics produces apps that compile, pass review and confidently display wrong answers. You integrate accelerometer data because the API returns acceleration values and integration is what programmers do with time-series data. Then you wonder why the parking dot teleports. Physics without computer science produces correct equations in notebooks that never survive Android foreground service rules, iOS background location limits, Compose recomposition jank, or ktuyen's test matrix — the one that caught compass drift on iPhone 15 in a steel-frame garage while the Pixel 8 sailed through. uranashel is three people precisely because the skill set has to span both. I write the sensor pipelines and the DSP. atuan makes the backend and release infrastructure real. ktuyen makes the quality gate real, in Vietnamese and English, on real devices in real garages. Stashio is the honest outlier in the catalogue: no physics anywhere, just the 2,400 unsorted links in my Apple Notes and the discovery that after three months of daily use, 94% of retrieval attempts finish in under 10 s. The [Stashio post](https://uranashel.com/blog/stashio-second-brain.html) explains why a sensor studio ships a save-for-later app. The answer is the same problem-first sequence with the physics swapped out. ## You do not need two degrees You need curiosity about the sensor underneath the API documentation, and honesty when the math says your UX is lying. A degree is one path to that honesty; garage logs are another. Garage logs at Landmark 81 taught me more about multipath than any textbook chapter did. Listening to an AC unit change pitch over three years taught me more about bearing degradation than any lecture. The [Lab page](https://uranashel.com/lab.html) on this site exists so you can reproduce some of those observations with the phone you already own. For the studio context, start with the [welcome post](https://uranashel.com/blog/welcome-uranashel.html) and follow the links wherever your curiosity points: magnetometer ellipsoids, pink noise spectra, Kalman covariance traces. --- uranashel · [Home](https://uranashel.com/) · [Apps](https://uranashel.com/apps.html) · [Lab](https://uranashel.com/lab.html) · [About](https://uranashel.com/about.html) · [Blog](https://uranashel.com/blog/) · [Developers](https://uranashel.com/developers/) · [API docs](https://uranashel.com/docs/) · [Privacy](https://uranashel.com/privacy.html) Machine-readable: [llms.txt](https://uranashel.com/llms.txt) · [sitemap.xml](https://uranashel.com/sitemap.xml) · [openapi.json](https://uranashel.com/openapi.json) · [API](https://uranashel.com/api/v1/)