PixelSat I Software Part 2: Attitude Determination and Control System<br>| Project Pixel OrbitalPixelSat I Software Part 2: Attitude Determination and Control System
by Ashwin Naren, Vinayak Vikram, and Aadish Verma<br>7/13/2026
Welcome to the second post in our series about the PixelSat I software stack. If you haven’t read Part 1 on our comms system, we’d recommend starting there for context on the mission.
Attitude Determination and Control System
Put simply, ADCS is the subsystem that answers two questions continuously throughout the mission: “Which way is the satellite currently pointing, and how fast is it rotating?” (determination) and “What do we need to do to point it somewhere else, or stop it from tumbling?” (control).
Like comms, ADCS is a subsystem where the “correct” solution used on larger missions (star trackers, reaction wheels, etc.) is completely out of reach for our budget. So a lot of this post is about the tradeoffs we made to get a working attitude system out of cheap, noisy, and somewhat sparse sensors.
Constraints
We cannot use reaction wheels or control moment gyroscopes.<br>On most higher-cost satellites, these are widely used, since they let you apply torque in any direction independent of your environment as well as simply generate much more torque.<br>However, due to the fact that they are a) expensive b) extremely mechanically complex (we’re trying to keep moving parts off this satellite) and c) draw power we don’t have to spare, we committed early to magnetorquers only.<br>Magnetorquers are wonderfully simple, provided you are comfortable letting Earth’s magnetic field participate in every steering decision.
We cannot use a star tracker either. We have neither the (cost) budget to get one (they require extremely good optics) nor the computing budget to process their data.
Finally, sensors need to be cheap, low power, and easy to interface with over standard buses (I2C, SPI) from our onboard computer.
Given those constraints, our sensor suite ended up being:
Coarse Sun Sensor : six photodiodes, one on each face of the satellite (+X, -X, +Y, -Y, +Z, -Z). Individually crude, but together they let us reconstruct a body-frame sun direction whenever the sun is visible.
Magnetometer (PNI RM3100-CB): gives us a body-frame measurement of Earth’s magnetic field, which we compare against a reference field.
Gyroscope : gives us angular velocity directly, and is the main sensor for short-timescale attitude propagation.
Our sole actuator is a set of three orthogonal magnetorquers, which produce a magnetic dipole that reacts against Earth’s local magnetic field to produce torque.<br>However, magnetorquers have one major drawback: they cannot generate arbitrary torques.<br>A magnetorquer produces a magnetic dipole mmm, which interacts with Earth’s magnetic field BBB according to
τ=m×B,τ⋅B=0.\tau=m\times B,<br>\qquad<br>\tau\cdot B=0.τ=m×B,τ⋅B=0.<br>Since the torque is always the cross product of these vectors, it is necessarily perpendicular to the local magnetic field. At any instant there is therefore one direction in which the spacecraft simply cannot produce torque.
Additionally, due to only having three magnetorquers, the strength of the produced magnetic dipole varies due to per-axis saturation.
Our system chooses the closest possible dipole direction to the desired torque direction. We solve this in a few ways, outlined later.
Attitude Determination System
Why an EKF
We have two very different kinds of sensor information to reconcile.
The gyro gives us a relative, high-rate measurement of angular velocity. However, it drifts over time, and can’t give us a stable reference: it gives us velocity, not position.
The sun sensor and magnetometer, on the other hand, give us absolute vector references, but at a lower rate and lower individual accuracy.<br>For example magnetometer readings are not taken while we are applying torque from the magnetorquers, as that heavily affects the readings.<br>Reading the magnetometer while running the magnetorquer would be a bit like checking a compass while holding a magnet right next to it.<br>Instead, we have to temporarily pause the magnetorquers every 500 ms to take a reading.<br>And while the coarse sun sensor is not affected by this, it remains far less accurate than either the magnetometer or the IMU.
The EKF combines these complementary measurements.<br>An EKF allows you to fuse a fast, drifting relative sensor with slower absolute references, weighted by how much you trust each one at any given moment.<br>“Extended” just means we linearize the (inherently nonlinear) attitude dynamics around our current best estimate at every step, rather than assuming everything is linear like a textbook Kalman filter would.
More specifically, the current implementation is a multiplicative error-state EKF.<br>What this means is that instead of tracking the full attitude as a linear filter state, we propagate the nominal attitude on its own using proper nonlinear quaternion kinematics, and...