Skip to main content

satellite_stabilization

#04 Lesson. Satellite stabilization

Satellite stabilization mode means maintaining zero angular velocity. Such a mode is necessary, for example, to obtain clear images or transmit them to a ground receiving point when the data transmission time is long and it is not permissible for the satellite antenna to deviate from the direction to the ground receiving point. The theory described in this lesson is also suitable for maintaining any required angular velocity, not just zero, for tasks such as tracking a moving object.

How to implement the stabilization mode

The angular velocity of the satellite can be changed using flywheels, jet engines, electromagnetic coils, gyrodyne engines. In this example, we will consider controlling the control torque using a flywheel. The operation of this device is based on the law of conservation of angular momentum. For example, when the flywheel engine spins in one direction, the spacecraft, accordingly, begins to rotate in the other direction under the action of the same torque, but directed in the opposite direction in accordance with Newton's third law. If, under the influence of external factors, the spacecraft began to turn in a certain direction, it is enough to increase the speed of rotation of the flywheel in the same direction and the undesirable rotation of the spacecraft will stop, instead of the satellite, the rotational moment will "absorb" the flywheel. We will receive information about the angular velocity of the satellite using an angular velocity sensor. In this example, we will consider how to calculate the control commands for the flywheel based on the readings of the angular velocity sensor and the data on the speed of rotation of the flywheel so that the satellite is stabilized or maintains the required angular velocity.

Theory

Analogies between translational and rotational motion

An analogue of the law of conservation of momentum for rotational motion is the law of conservation of angular momentum or the law of conservation of kinetic momentum:

i=1nJiωi=const\sum\limits_{i=1}^{n}{{{J}_{i}}\cdot {{\omega }_{i}}}=const

In general, the rotational motion of a satellite is described by laws similar to those known for translational motion. So, for example, for each parameter in translational motion there is a similar parameter for rotational motion:

Laws of Motion

The laws of motion also look similar

![Laws of Motion]

Output of the ratio for the required angular velocity of the flywheel

Let's write down the law of conservation of the kinetic moment of the satellite+flywheel system for the moments of time "1" and "2":

Jsωs1+Jmωm1=Jsωs2+Jmωm2{{J}_{s}}\cdot {{\omega }_{s1}}+{{J}_{m}}\cdot {{\omega }_{m1}}={{J}_{s}}\cdot {{\omega }_{s2}}+{{J}_{m}}\cdot {{\omega }_{m2}}

The absolute speed of the flywheel, i.e. the speed of the flywheel in an inertial coordinate system, for example, connected to the Earth, is the sum of the angular velocity of the satellite and the angular velocity of the flywheel relative to the satellite, i.e. the relative angular velocity of the flywheel:

ωmi=ωsi+ωmi{{\omega }_{mi}}={{\omega }_{si}}+{{{\omega }'}_{mi}}

Please note that the flywheel can measure its own angular velocity relative to the satellite body or relative angular velocity.

Let's express the angular velocity of the flywheel, which must be set

Jsωs1+Jm(ωs1+ωm1)=Jsωs2+Jm(ωs2+ωm2){{J}_{s}}\cdot {{\omega }_{s1}}+{{J}_{m}}\cdot \left( {{\omega }_{s1}}+{{{{\omega }'}}_{m1}} \right)={{J}_{s}}\cdot {{\omega }_{s2}}+{{J}_{m}}\cdot \left( {{\omega }_{s2}}+{{{{\omega }'}}_{m2}} \right)
(Js+Jm)(ωs1ωs2)=Jm(ωm1ωm2)\left( {{J}_{s}}+{{J}_{m}} \right)\left( {{\omega }_{s1}}-{{\omega }_{s2}} \right)=-{{J}_{m}}({{\omega }_{m1}}-{{\omega }_{m2}})
ωm2=ωm1+Js+JmJm(ωs1ωs2){{\omega }_{m2}}={{\omega }_{m1}}+\frac{{{J}_{s}}+{{J}_{m}}}{{{J}_{m}}}\left( {{\omega }_{s1}}-{{\omega }_{s2}} \right)

Let's denote the relation Js+JmJm\frac{{{J}_{s}}+{{J}_{m}}}{{{J}_{m}}} as kdk_d.

For the algorithm to work, it is not necessary to know the exact value of Js+JmJm\frac{{{J}_{s}}+{{J}_{m}}}{{{J}_{m}}}, because the flywheel cannot instantly set the required angular velocity. Measurement noises also interfere with the control process: the angular velocity of the satellite measured using an angular velocity sensor is not accurate, because there is always a constant error and measurement noise in the measurements. It should be noted that angular velocity measurements and the issuance of commands to the flywheel occur with a certain minimum step in time. All these limitations lead to the fact that kdk_d is selected experimentally or detailed computer models are built that take into account all the above limitations. In our case, the coefficient kdk_d will be selected experimentally.

ωm2=ωm1+kd(ωs1ωs2){{\omega }_{m2}}={{\omega }_{m1}}+{{k}_{d}}\left( {{\omega }_{s1}}-{{\omega }_{s2}} \right)

Angular velocity ωs2\omega_{s2} at time "2" is the target angular velocity, let's denote it ωs_goal\omega_{s\_goal}. Thus, if it is necessary that the satellite maintain the angular velocity of ωs_goal\omega_{s\_goal}, then knowing the current angular velocity of the satellite and the current angular velocity of the flywheel, it is possible to calculate the desired flywheel speed to maintain the "rotation at constant speed" mode:

ωm2=ωm1+kd(ωs1ωs_goal){{\omega }_{m2}}={{\omega }_{m1}}+{{k}_{d}}\left( {{\omega }_{s1}}-{{\omega }_{{s\_goal}}} \right)

Using the constant speed rotation mode, you can make the satellite turn at any angle if you rotate the satellite at a constant speed for a certain time. Then the time it takes to rotate the satellite at a constant speed ωs_goal\omega_{s\_goal} to turn around at the required angle α\alpha is determined by dividing these values:

t=αωs_goalt=\frac{\alpha}{\omega_{{s\_goal}}}

If it is required that the satellite be stabilized, then ωs_goal=0\omega_{s\_goal}=0 and the expression takes on a simpler form:

ωm2=ωm1+kdωs1{{\omega }_{m2}}={{\omega }_{m1}}+{{k}_{d}}\cdot {{\omega }_{s1}}

Python implementation

Example using a formula in a Python code example:

# Requesting satellite Angular Velocity (AVS) and flywheel data
hyro_state, gx_raw, gy_raw, gz_raw = hyro_request_raw(hyr_num)
mtr_state, mtr_speed = motor_request_speed(mtr_num)

# converting angular velocity values to degrees/sec
gx_degs = gx_raw * 0.00875

# if the AVS is set with the z axis up, then the angular velocity
The satellite's # matches the AVS readings on the z axis, otherwise
# the sign must be changed: omega = - gz_degs
omega = gz_degs

mtr_new_speed = int(mtr_speed+ kd*(omega-omega_goal))

Example of the full code of the satellite stabilization program in Python:

``cpp stab.py

Differential feedback coefficient.

The coefficient is positive if the flywheel is positioned with the z axis up

and AVS is positioned with the z axis also up.

The coefficient is selected experimentally depending on the shape

and the mass of your satellite.

kd = 200.0

Time step of the algorithm, with

time_step = 0.1

Target angular velocity of the satellite, deg/s.

For stabilization mode is 0.0.

omega_goal = 0.0

Flywheel number

mtr_num = 1

Maximum permissible flywheel speed, rpm

mtr_max_speed = 5000

AVS (Angular Velocity sensor) number

hyr_num = 1

Functions for determining the new flywheel speed.

The new flywheel speed is made up of

the current flywheel speed and the speed increment.

The speed increment is proportional to the angle error

and an error in angular velocity.

mtr_speed - current angular velocity of the flywheel, rpm

omega - the current angular velocity of the satellite, deg/s

omega_goal - target angular velocity of the satellite, deg/s

mtr_new_speed - required angular velocity of the flywheel, rpm

def motor_new_speed_PD(mtr_speed, omega, omega_goal): mtr_new_speed = int(mtr_speed + kd*(omega-omega_goal)) if mtr_new_speed > mtr_max_speed: mtr_new_speed = mtr_max_speed elif mtr_new_speed < -mtr_max_speed: mtr_new_speed = -mtr_max_speed return mtr_new_speed

The function includes all devices,

which will be used in the main program.

def initialize_all(): print "Enable motor №", mtr_num motor_turn_on(mtr_num) sleep(1) print "Enable angular velocity sensor №", hyr_num hyro_turn_on(hyr_num) sleep(1)

The function turns off all devices,

which will be used in the main program.

def switch_off_all(): print "Finishing..." print "Disable angular velocity sensor №", hyr_num hyro_turn_off(hyr_num) motor_set_speed(mtr_num, 0) sleep (1) motor_turn_off(mtr_num) print "Finish program"

The main function of the program in which the rest of the functions are called.

def control(): initialize_all()

Initialize the flywheel status

mtr_state = 0
# Initialize the status of AVS

hyro_state = 0 omega_goal = 0.0

for i in range(1000): print "i = ", i

Polling the angular velocity sensor and flywheel.

    hyro_state, gx_raw, gy_raw, gz_raw = hyro_request_raw(hyr_num)

mtr_state, mtr_speed = motor_request_speed(mtr_num)

Processing of angular velocity sensor readings,

calculation of satellite angular velocity based on AVS readings.

    # If the AVS error code is 0, i.e. there is no error
if not hyro_state:
gx_degs = gx_raw * 0.00875
gy_degs = gy_raw * 0.00875
gz_degs = gz_raw * 0.00875
# if the AVS is set with the z axis up, then the angular velocity
The satellite's # matches the AVS readings on the z axis, otherwise
# the sign must be changed: omega = - gz_degs
omega = gz_degs
print "gx_degs =", gx_degs, "gy_degs =", gy_degs, "gz_degs =", gz_degs
elif hyro_state == 1:
print "Fail because of access error, check the connection"
elif hyro_state == 2:
print "Fail because of interface error, check your code"

#Processing the flywheel readings and setting the required angular velocity.
if not mtr_state: # if the error code is 0, i.e. there is no error
print "Motor_speed: ", mtr_speed
# setting the new flywheel speed
mtr_new_speed = motor_new_speed_PD(mtr_speed,omega,omega_goal)
motor_set_speed(mtr_num, mtr_new_speed)

sleep(time_step)

switch_off_all()

## Implementation in C
### Example of the full satellite stabilization program code in C:

```cpp stab.c
#include "libschsat.h"
const float kd = 200.0;

// The time step of the algorithm, with
const float time_step = 0.2;

// The target angular velocity of the satellite, deg/s
. // For stabilization mode is 0.0.
const float omega_goal = 0.0;

// The number of the flywheel
const int mtr_num = 1;

// Maximum permissible flywheel speed, rpm
const int mtr_max_speed = 5000;

// AVS (Angular Velocity Sensor) number
const uint16_t hyr_num = 1;
int16_t mtr_new_speed;
int motor_new_speed_PD(int mtr_speed, int omega, float omega_goal){
/* Function for determining the new flywheel speed.
The new flywheel speed is made up of
the current flywheel speed and the speed increment.
The speed increment is proportional to the angle error and the angular velocity error.
mtr_speed - current angular velocity of the flywheel, rpm
omega - current angular velocity of the satellite, deg/s
omega_goal - target angular velocity of the satellite, deg/s
mtr_new_speed - required angular velocity of the flywheel, rpm*/

mtr_new_speed = (int)(mtr_speed + kd * (omega - omega_goal));

if (mtr_new_speed > mtr_max_speed)
{
mtr_new_speed = mtr_max_speed;
}
else if (mtr_new_speed < -mtr_max_speed)
{
mtr_new_speed = -mtr_max_speed;
}
return mtr_new_speed;
}

void initialize_all(void){
/*The function includes all devices that will be used in the main program.*/
printf("Enable motor no.%d\n", mtr_num);
motor_turn_on(mtr_num);
Sleep(1);
printf("Enable angular velocity sensor №%d\n", hyr_num);
hyro_turn_on(hyr_num);
Sleep(1);
}

void switch_off_all(void){
/* The function disables all devices that will be used in the main program.*/
printf("Finishing...");
int16_t new_speed = mtr_new_speed; //
printf("\nDisable angular velocity sensor no.%d\n", hyr_num);
hyro_turn_off(hyr_num);
motor_set_speed(mtr_num, 0, &new_speed);
Sleep (1);
motor_turn_off(mtr_num);
printf("Finish program\n");
}

void control(void){
initialize_all();
// Initializing the flywheel status
int16_t mtr_state;
// Initialize the status of AVS
int16_t hyro_state = 0;
int16_t pRAW_dataX = 0;
int16_t pRAW_dataY = 0;
int16_t pRAW_dataZ = 0;
int16_t *gx_raw = &pRAW_dataX;
int16_t *gy_raw = &pRAW_dataY;
int16_t *gz_raw = &pRAW_dataZ;
int16_t speed = 0;
int16_t *mtr_speed = &speed;
int16_t omega;
int i;
for(i = 0; i < 1000; i++){
printf("i = %d\n", i);
// Polling of the angular velocity sensor and flywheel.
hyro_state = hyro_request_raw(hyr_num, gx_raw, gy_raw, gz_raw);
mtr_state = motor_request_speed(mtr_num, mtr_speed);

// Processing of angular velocity sensor readings,
// calculation of the angular velocity of the satellite according to AVS readings.
// If the AVS error code is 0, i.e. there is no error
if (!hyro_state){
float gx_degs = *gx_raw * 0.00875;
float gy_degs = *gy_raw * 0.00875;
float gz_degs = *gz_raw * 0.00875;
// if AVS is set with the z axis up, then the angular velocity
// of the satellite coincides with the AVS readings along the z axis, otherwise
// the sign must be changed: omega = - gz_degs
omega = gz_degs;
printf("gx_degs = %f ", gx_degs);
printf(" gy_degs = %f ", gy_degs);
printf(" gz_degs = %f\n", gz_degs);
}
else if (hyro_state == 1){
printf("Fail because of access error, check the connection\n");
}
else if (hyro_state == 2){
printf("Fail because of interface error, check your code\n");
}

int mtr_new_speed;
//Processing the flywheel readings and setting the required angular velocity.
if (!mtr_state) {
// if the error code is 0, i.e. there is no error
int16_t mtr_speed=0;
motor_request_speed(mtr_num, &mtr_speed);
printf("Motor_speed: %d\n", mtr_speed);
// setting the new flywheel speed
mtr_new_speed = motor_new_speed_PD(mtr_speed,omega,omega_goal);
motor_set_speed(mtr_num, mtr_new_speed, &omega);
}
}
Sleep(time_step);
switch_off_all();
}

A task for independent work

  1. Change the program so that the satellite rotates at a constant speed.

  2. Change the program so that the satellite works according to the following cyclogram:

  • stabilization for 10 seconds;
  • 180 degree turn in 30 seconds;
  • stabilization again within 10 seconds.
  1. Rewrite the program in C and make it work.