Spacecraft pointing control is an essential technology for all robotic and manned spacecraft. A control system consists of sensing, actuation, and the dynamics of the spacecraft itself. Spacecraft control systems are of many types, but in this chapter, we will be concerned only with three axis pointing. We will use reaction wheels for actuation.

Reaction wheels are used for control through the conservation of angular momentum. The torque on the reaction wheel causes it to spin one way and the spacecraft to spin in the opposite direction. Momentum removed from the spacecraft is absorbed in the wheel. Reaction wheels are classified as momentum exchange devices because they exchange momentum with the rest of the spacecraft. You can reorient the spacecraft using reaction wheels without any external torques. Before reaction wheels were introduced, thrusters were often used for orientation control. This would consume the propellant which is undesirable since when you run out of propellant, the spacecraft can no longer be used.

The spacecraft is modeled as a rigid body except for the presence of three reaction wheels that rotate about orthogonal (perpendicular) axes. One rotates about the x axis, one rotates about the y axis, and the third about the z axis. The shaft of the motor is attached to the rotor of the wheel which is attached to the spacecraft. The torque applied between the wheel and spacecraft causes the wheel and spacecraft to move in opposite angular directions. We will assume that we have attitude sensors that measure the orientation of the spacecraft. We will also assume that our wheels are ideal with just viscous damping friction.

1 Creating a Dynamical Model of the Spacecraft

1.1 Problem

The spacecraft is a rigid body with three wheels. Each wheel is connected to the spacecraft as shown in Figure 13.1.

Figure 13.1
figure 1

A reaction wheel. The reaction wheel platter spins in one direction, and the spacecraft spins in the opposite direction.

1.2 Solution

The equations of motion are written using angular momentum conservation. This produces a dynamical model known as the Euler equations with the addition of the spinning wheels. This is sometimes known as a gyrostat model.

1.3 How It Works

The spacecraft model can be partitioned into dynamics, including the dynamics of the reaction wheels, and the kinematics of the spacecraft. If we assume that the wheels are perfectly symmetric, are aligned with the three body axes, and have a diagonal inertia matrix, we can model the spacecraft dynamics with the following coupled first-order differential equations:

$$\displaystyle \begin{aligned} \begin{array}{rcl} I\dot{\omega} + \omega^\times\left(I\omega + I_w(\omega_w+ \omega)\right) + I_w(\dot{\omega}_w+\dot{\omega}) & =&\displaystyle T \end{array} \end{aligned} $$
(13.1)
$$\displaystyle \begin{aligned} \begin{array}{rcl} I_w\left(\dot{\omega}_w + \dot{\omega}\right) & =&\displaystyle T_w \end{array} \end{aligned} $$
(13.2)

I is the 3-by-3 inertia matrix of the spacecraft and does not include the inertia of the wheels.

$$\displaystyle \begin{aligned} I = \left[ \begin{array}{lll} I_{xx}& I_{xy} & I_{xz}\\ I_{yx}& I_{yy} & I_{yz}\\ I_{zx}& I_{zy} & I_{zz} \end{array} \right] \end{aligned} $$
(13.3)

The inertia matrix is symmetric so I xy = I yx, I xz = I zx, I zy = I yz. ω is the angular rate vector for the spacecraft seen in the spacecraft frame.

$$\displaystyle \begin{aligned} \omega = \left[ \begin{array}{l} \omega_x\\ \omega_y\\ \omega_z \end{array} \right] \end{aligned} $$
(13.4)

ω w is the angular rate of the reaction wheels:

$$\displaystyle \begin{aligned} \omega_w = \left[ \begin{array}{l} \omega_1\\ \omega_2\\ \omega_3 \end{array} \right] \end{aligned} $$
(13.5)

for wheels 1, 2, and 3. 1 is aligned with x, 2 with y, and 3 with z. In this way, the reaction wheels form an orthogonal set and can be used for three-axis control. T is the external torque on the spacecraft which can include external disturbances such as solar pressure or aerodynamic drag and thruster or magnetic torquer coil torques. T w is the internal torque on the wheels; I w is the scalar polar inertia of the wheels (we assume that they all have the same polar inertia). We can substitute the second equation into the first to simplify the equations.

$$\displaystyle \begin{aligned} \begin{array}{rcl} I\dot{\omega} + \omega^\times\left(I\omega + I_w(\omega_w+ \omega)\right) + T_w& =&\displaystyle T \end{array} \end{aligned} $$
(13.6)
$$\displaystyle \begin{aligned} \begin{array}{rcl} I_w\left(\dot{\omega}_w + \dot{\omega}\right) & =&\displaystyle T_w \end{array} \end{aligned} $$
(13.7)

This term

$$\displaystyle \begin{aligned} T_e = \omega^\times\left(I\omega + I_w(\omega_w+ \omega)\right) \equiv \omega \times h \end{aligned} $$
(13.8)

is known as the Euler torque. If the angular rates are small, we can set this term to zero and the equations simplify to

$$\displaystyle \begin{aligned} \begin{array}{rcl} I\dot{\omega} + T_w& =&\displaystyle T{} \end{array} \end{aligned} $$
(13.9)
$$\displaystyle \begin{aligned} \begin{array}{rcl} I_w\left(\dot{\omega}_w + \dot{\omega}\right) & =&\displaystyle T_w \end{array} \end{aligned} $$
(13.10)

For kinematics, we will use quaternions. A quaternion is a four-parameter representation of the orientation of the spacecraft with respect to the inertial frame. We could use angles since we really only need three states (dynamical quantities) to specify the orientation. The problem with Euler angles is that they introduce singularities, that is, certain orientations where an angle is undefined, and therefore they are not suitable for simulations. The derivative of the quaternion from the inertial frame to the body frame is

$$\displaystyle \begin{aligned} \dot{q} = \frac{1}{2}\left[ \begin{array}{rr} 0 & \omega^T\\ -\omega & \omega^\times \end{array} \right] \end{aligned} $$
(13.11)

The term ω × is the skew symmetric matrix that is the equivalent of the cross product and is

$$\displaystyle \begin{aligned} \omega^\times = \left[ \begin{array}{rrr} 0 & -\omega_z & \omega_y \\ \omega_z & 0 & -\omega_x\\ -\omega_y & \omega_x & 0 \end{array} \right] \end{aligned} $$
(13.12)

The skew matrix always has zeros on the diagonal, and the matrix is equal to the negative of its transpose. The wheel torque is a combination of friction torque and control torque. Reaction wheels are usually driven by brushless direct current (DC) motors that have the back electromotive force canceled by current feedback within the motor electronics. The total reaction wheel torque is therefore

$$\displaystyle \begin{aligned} T_w = T_c + T_f \end{aligned} $$
(13.13)

where T c is the commanded reaction wheel torque and T f is the friction torque. A simple friction model is

$$\displaystyle \begin{aligned} T_f = - k_d\omega_k \end{aligned} $$
(13.14)

k d is the damping coefficient. If k d is large, we can compensate for it proactively by feeding the expected friction torque forward into the controller. This requires careful calibration of the wheel to determine the damping coefficient.

First, we will define the data structure for the model that is returned by the dynamics right-hand-side function if there are no inputs. The name of the function is RHSSpacecraftWith RWA.m. We use RWA to mean “Reaction Wheel Assembly.” We say “assembly” because the reaction wheel is assembled from bearings, wheel, shaft, support structure, and power electronics. Spacecraft are built up of assemblies.

The default unit vectors for the wheel are along orthogonal axes, that is, x, y, and z. The default inertia matrix is the identity matrix, making the spacecraft a sphere. The default reaction wheel inertias are 0.001. All of the nonspinning parts of the wheels are lumped in with the inertia matrix.

RHSSpacecraftWithRWA.m

The dynamical equations for the spacecraft are given in the following lines of code. We need to compute the total wheel torque because it is applied both to the spacecraft and the wheels. We use the backslash operator to multiply the equations by the inverse of the inertia matrix. The inertia matrix is positive definite symmetric so specialized routines can be used to speed computation of this inverse. It is a good idea to avoid computing inverses as they can be ill-conditioned, meaning that small errors in the matrix can result in large errors in the inverse.

We save the elements of the state vector as local variables with meaningful names to make reading the code easier. This also eliminates unnecessary multiple extraction of submatrices.

You will notice that the omegaRWA variable reads from element 8 to the end of the vector using the end keyword. This allows the code to handle any number of reaction wheels. You might just want to control one axis with a wheel or have more than three wheels for redundancy. Be sure that the inputs in d match the number of wheels. We also input unit vectors for each wheel. The unit vector is the axis or rotation for each. As a consequence, the wheels do not have to be aligned with x, y, and z, that is, do not have to be orthogonal.

Note that uRWA is an array of the reaction wheel unit vectors, that is, the spin vectors. In computing h, we have to transform ω into the wheel frame using the transpose of uRWA and then transform back before adding the wheel component to the core component, . The wheel dynamics are given next, note the use of the backslash operator to solve the set of linear equations for \(\dot {\omega }\), omegaDotCore:

The total state derivative is in these lines:

The total inertial angular momentum is an auxiliary output. In the absence of external torques, it should be conserved so it is a good test of the dynamics. A simple way to test angular momentum conservation is to run a simulation with anger rates for all the states and then rerun it with a smaller time step. The change in angular momentum should decrease as the time step is decreased.

2 Computing Angle Errors from Quaternions

2.1 Problem

We want to point the spacecraft to a new target attitude (orientation) with the three reaction wheels or maintain the attitude given an external torque on the spacecraft.

2.2 Solution

We will make three proportional-derivative (PD) controllers, one for each axis. We need a function to take two quaternions and compute the small angles between them as input to these controllers.

2.3 How It Works

If we are pointing at an inertial target and wish to control about that orientation, we can simplify the rate equations by approximating ω as \(\dot {\theta }\) which is valid for small angles when the order of rotation doesn’t matter and the Euler angles can be treated as a vector.

$$\displaystyle \begin{aligned} \dot{\theta} = \omega \end{aligned} $$
(13.15)

We will also multiply both sides of the Euler equation, Equation 13.9, by I −1, to solve for the derivatives. Note that T w, the torque from the wheels, is equivalent to Ia w, where a is the acceleration. Our system equations now become

$$\displaystyle \begin{aligned} \begin{array}{rcl} \ddot{\theta} + a_w& =&\displaystyle a \end{array} \end{aligned} $$
(13.16)
$$\displaystyle \begin{aligned} \begin{array}{rcl} I_w\left(\dot{\omega}_w + \dot{\omega}\right) & =&\displaystyle -T_w \end{array} \end{aligned} $$
(13.17)

The first equation is now three decoupled second-order equations, just as in our Chapter 7. We can stabilize this system with our standard PD controller.

We need attitude angles as input to the PD controllers to compute our control torques. Our examples will only be for small angular displacements from the nominal attitude. We will pass the control code a target quaternion, and it will compute Δ angles, or we will impose a small disturbance torque.

In these cases, the attitude can be treated as a vector where the order of the rotations doesn’t matter. A quaternion derived from small angles is

$$\displaystyle \begin{aligned} q_\varDelta \approx \left[ \begin{array}{c} 1\\ -\theta_{1}/2\\ -\theta_{2}/2\\ -\theta_{3}/2\\ \end{array} \right] \end{aligned} $$
(13.18)

We find the required error quaternion q Δ by multiplying the target quaternion, q T, with the transpose of the current quaternion:

$$\displaystyle \begin{aligned} q_\varDelta = q^Tq_T \end{aligned} $$
(13.19)

This algorithm to compute the angles is implemented in the following code. The quaternion multiplication is made a subfunction. This makes the code cleaner and easier to see how it relates to the algorithm. QMult is written to handle multiple quaternions at once so the function is easy to vectorize. QPose finds the transpose of the quaternion. Both of these functions would normally be separate functions, but in this chapter, they are only associated with the error computation code so we put them in the same file.

ErrorFromQuaternion.m

The control system is implemented in the simulation loop (in the next recipe) with the following code:

SpacecraftSim.m

3 Simulating the Controlled Spacecraft

3.1 Problem

We want to test our attitude controller and see how it performs.

3.2 Solution

The solution is to build a MATLAB script in which we design the PD controller matrices and then simulate the controller in a loop, applying the calculated torques until the desired quaternion is attained or until the disturbance torque is canceled.

3.3 How It Works

We build a simulation script for the controller, SpacecraftSim. The first thing we do with the script is to set parameters at the top of the file to check the angular momentum conservation by running the simulation for 300 seconds at time steps of 0.1 and 1 second and comparing the magnitude of the angular momentum in the two test cases. The control is turned off by setting the controlIsOn flag to false. In the absence of external torques, if our equations are programmed correctly, the momentum should be constant. We will however see the growth in the momentum due to error in the numerical integration. The growth should be much lower in the first case than the second case as the smaller time step makes the integration more exact. Remember that for fourth-order Runge-Kutta, the error goes as the fourth power of the time step. Note that we give the spacecraft random initial rates in both omega and omegaRWA and a nonspherical inertia to help catch any bugs in the dynamics code.

Figure 13.2 shows the results of the tests using the above initialization code. The momentum growth is four orders of magnitude lower in the test with a 0.1 second time step indicating that the dynamical equations conserve angular momentum as they should. The shape of the growth does not change and will depend on the relative magnitudes of the various angular rates.

Figure 13.2
figure 2

Angular momentum conservation for 1 second and 0.1 second time steps. The growth is four orders of magnitude lower in the 0.1 second test, to 1e−13 from 1e−9.

We initialize the script by using our data structure feature of the RHS function. This is shown in the following with parameters for a run with the control system on. The rates are now initialized to zero, and we use the time step of 1 second, which showed sufficiently small momentum growth in our previous test.

The control system is designed here. Note the small value of wN and the unit damping ratio. The frequency of the disturbances on a spacecraft is quite low, and the wheels have torque limits, leading to a wN much smaller than the robotics recipe. All three controllers are identical.

The simulation loop follows. As always, we initialize the plotting array with zeros. By allocating memory for the array, we speed up the code as memory allocation is usually slow. The first step in the loop is finding the angular error between the current state and the target attitude. Next, the control acceleration is calculated or set to zero, depending on the value of the control flag. The control torque is calculated by multiplying the control acceleration by the spacecraft inertia. We compute the momentum for plotting purposes and, finally, integrate one time step.

Our output is entirely two-dimensional plots. We break them up into pages with one to three plots per page. This makes them easily readable on most computer displays.

Note how PlotSet makes plotting much easier to set up and read code than if we use MATLAB’s built-in plot and supporting functions. You do lose some flexibility. The y axis labels use LaTeX notation. LaTeX is a technical publications package. This provides limited LaTeX syntax, such as Greek letters, subscripts, and superscripts. You can set the plotting to full LaTeX mode to get access to all LaTeX commands and formatting.

Note that we compute the angle error directly from the target and true quaternion. This represents our attitude sensor. In real spacecraft, attitude estimation is quite complicated. Multiple sensors, such as combinations of magnetometers, GPS, and earth and sun sensors, are used, and often rate-integrating gyros are employed to smooth the measurements. Star cameras or trackers are popular for three-axis sensing and require converting images in a camera to attitude estimates. You can’t use gyros by themselves because they do not provide an initial orientation with respect to the inertial frame.

We will run two tests. The first shows that our controllers can compensate for a body-fixed disturbance torque. The second is to show that the controller can reorient the spacecraft.

The following is the initialization code for the disturbance torque test. The initial and target attitudes are the same, a unit quaternion, but there is a small disturbance torque.

We are running the simulations to 600 seconds to see the transients settle out. The disturbance torque is very small, which is typical for spacecraft. We make the torque single axis to make the responses clearer. Figure 13.3 shows the complete set of output plots.

Figure 13.3
figure 3

Controlling a suddenly applied external torque.

The disturbance causes a change in attitude around the y axis. This offset is expected with a PD controller. The control torque eventually matches the disturbance, and the angular error reaches its maximum. The PD control method will have steady-state error for constant (or more generally, nonzero-mean) disturbances. The integral control would be required to compensate for such disturbances.

The y wheel rate grows linearly as it has to absorb all the momentum produced by the torque. We don’t limit the maximum wheel rate. In a real spacecraft, the wheel would soon saturate, reaching its maximum allowed speed. Our control system would need to have other actuators to desaturate the wheel. The inertial angular momentum also grows linearly as is expected with a constant external torque.

We now do an attitude correction around the x axis. The following is the initialization code:

We command a small attitude offset around the x axis, which is done by changing the second element in the quaternion. We unitize the quaternion to prevent numerical issues. Figure 13.4 shows the output plots.

Figure 13.4
figure 4

Response to a small change in attitude.

In this case, the angular error around the x axis is reduced to zero. The inertial angular momentum remains “constant” although it jumps around a bit due to truncation error in the numerical integration. This is expected and it is good to keep checking the angular momentum with the control system running. If it doesn’t remain nearly constant, it means that the simulation probably has an error in the dynamical equations. Internal torques do not change the inertial angular momentum. This is why reaction wheels are called “momentum exchange devices.” They exchange momentum with the spacecraft body but don’t change the total inertial angular momentum.

The attitude rates remain small in both cases so that the Euler coupling torques are small. This justifies our earlier decision to treat the spacecraft as three double integrators. It also justifies our quaternion error to small angle approximation.

4 Performing Batch Runs of a Simulation

4.1 Problem

We’ve used our simulation script to verify momentum conservation and test our controller, but note how we have to change lines at the top by hand for each case. This is fine for development but can make it very difficult to reproduce results; we don’t know the initial conditions that generated any particular plot. We may want to run our simulation for a whole set of inputs and do a Monte Carlo analysis.

4.2 Solution

We’ll create a new function based on our script with inputs for our critical parameters. A new data structure will store both our inputs and the outputs so we can save individual runs to mat-files. This will make it possible to replot the results of any run in the future, or redo runs from the stored inputs, for example, if you find and fix a bug in the controller.

4.3 How It Works

Start from the simulation script copied into a new file. Add a function signature. Replace the initialization variables with an input structure. Perform the simulation, then save the input structure along with your generated output. The resulting function header is shown in the following listing. The input structure includes our RHS data, controller data, and simulation timing data.

SpacecraftSimFunction.m

Now, we can write a script that calls our simulation function in a loop. The possibilities are endless – you can test different targets, vary the initial conditions for a Monte Carlo simulation, and apply different disturbance torques. You can perform statistical analysis on your results or identify and plot individual runs based on some criteria. In this example, we will find the maximum control torque applied in each run.

BatchSimRuns.m

Figure 13.5 shows the maximum torque results. Each run has a larger initial angular velocity. We expect to see this trend, because the torque control is proportional to the angular rate.

Figure 13.5
figure 5

Maximum control torque over ten simulation runs.

An individual run’s output is shown as follows:

As another interesting example, we can give the spacecraft a higher initial rate and see how the controller responds. From the command line, we change the initial rate around the x axis to be 0.2 rad/sec and call the simulation function with no outputs, so that it will generate the full suite of plots. We see that the response takes a long time, over 20 minutes, but the rate does eventually damp out. Figure 13.6 shows the damping response.

Figure 13.6
figure 6

Control response to a large rate in x. The rate does damp out, eventually!

The full simulation function is shown in the following. The built-in demo performs an open loop simulation of the default spacecraft model with no control, as with the momentum conservation test performed in the previous recipe (Figure 13.2).

The plotting code is put into a separate function that accepts the output data structure. We create and save the plot labels in the simulation function. This allows us to replot any saved output. We add a statement to check for nonzero angle errors before creating the control and angle error plots, since they are not needed for open loop simulations.

TIP

Use the fields in your structure for plotting without renaming the variables locally, so you can copy/paste individual plots to the command line after doing a run of your simulation.

PlotSpacecraftSim.m

An interesting exercise for the reader would be to replace the fixed disturbance input, d.torque, with a function handle that calls a disturbance function. This forms the basis of spacecraft simulation in our Spacecraft Control Toolbox, where the disturbances are calculated from the spacecraft geometry and space environment as it rotates and moves along its orbit.

Summary

This chapter has demonstrated how to write the dynamics and implement a simple control law for a spacecraft with reaction wheels. Our control system is only valid for small angle changes and will not work well if the angular rates on the spacecraft get large. In addition, we do not consider the torque or momentum limits on the reaction wheels. We also learned about quaternions and how to implement kinematics of rigid body with quaternions. We showed how to get angle errors from two quaternions. Table 13.1 lists the code developed in the chapter.

Table 13.1 Chapter Code Listing