Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified Docs/FSW Models.pdf
Binary file not shown.
16 changes: 8 additions & 8 deletions Docs/FSW Models.tex
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
\begin{tabular}{@{} rl @{}}
{\bf To:} & 42 Users\\
{\bf From:} & Eric Stoneking \\
{\bf Date:} & July 2022 \\
{\bf Date:} & March 2025 \\
{\bf Subject:} & Getting Started with 42 Flight Software Models\\
\hline
\end{tabular}
Expand All @@ -36,13 +36,13 @@ \subsection{\tt PASSIVE\_FSW}

Passive FSW does nothing. It exerts no forces or torques. It is most useful for studying natural motion, passively-stabilized spacecraft, and out-of-control (eg. decommissioned) spacecraft. In the {\tt Demo} folder, the Moai, Big Black Monolith, and the three cubesats are using the passive FSW. BBM is demonstrating the natural motion due to an initial angular rate about the intermediate axis of inertia.

\subsection{\tt PROTOTYPE\_FSW}
\subsection{\tt INSTANT\_FSW}

As its name implies, prototype FSW is most useful for quick starts and very early studies. It uses inputs from the command script file (eg. {\tt Inp\_Cmd.txt}) to define a commanded attitude. See {\tt Inp\_Cmd.txt} for command templates and examples. The function {\tt PrototypeFSW} then controls the attitude to comply with the command. In the {\tt Demo} folder, the Shuttle and Ion Cruiser are using the prototype FSW. In the InOut folder, {\tt SC\_Simple.txt} is using prototype FSW.
As its name implies, instant FSW is most useful for quick starts and very early studies. It uses inputs from the command script file (eg. {\tt Inp\_Cmd.txt}) to define a commanded attitude. See {\tt Inp\_Cmd.txt} for command templates and examples. The function {\tt InstantFSW} then controls the attitude to comply with the command. In the {\tt Demo} folder, the Shuttle and Ion Cruiser are using the instant FSW. In the InOut folder, {\tt SC\_Simple.txt} is using instant FSW.

\subsection{\tt AD\_HOC\_FSW}
\subsection{\tt SANDBOX\_FSW}

This model is intended as the best jumping-off point for customization. As shipped, it is simply a proportional-derivative (PD) linear feedback to align the spacecraft with the inertial $N$ frame, using ideal torquers for actuation. It is up to you to modify the sensor inputs, commanded attitude, control law, and actuator commanding to fit your situation. In the {\tt Demo} folder, Voyager is running ad hoc FSW.
This model is intended as the best jumping-off point for customization. As shipped, it is simply a proportional-derivative (PD) linear feedback to align the spacecraft with the inertial $N$ frame, using ideal torquers for actuation. It is up to you to modify the sensor inputs, commanded attitude, control law, and actuator commanding to fit your situation. In the {\tt Demo} folder, Voyager is running sandbox FSW.

\subsection{\tt THREE\_AXIS\_FSW}

Expand All @@ -64,13 +64,13 @@ \subsection{And Beyond}

\section{Sensor Models}

In a simulation, sensors are one interface between the truth model (environment, dynamics) and the FSW model. In general terms, a sensor model takes the truth, perhaps adds some noise or other errors, and repackages the result in the proper format for the FSW model. In 42, the function {\tt 42sensors.c:Sensors} has some very simple sensor models provided. For example, the IMU model simply copies the true angular rate of the spacecraft's main body into the FSW data structure. It's up to you to embellish this model to reflect the realities of your sensor hardware to whatever fidelity you require.
In a simulation, sensors are one interface between the truth model (environment, dynamics) and the FSW model. In general terms, a sensor model takes the truth, perhaps adds some noise or other errors, and repackages the result in the proper format for the FSW model. In 42, the function {\tt 42sensors.c:Sensors} has some very simple sensor models provided. For example, the IMU model simply copies the true angular rate of the spacecraft's main body into the FSW data structure. It's up to you to customize this model to reflect the realities of your sensor hardware to whatever fidelity you require.

\section{Actuator Models}

Actuators are the other interface between the truth model and the FSW model. An actuator model accepts commands from the FSW model (eg. wheel torque commands, or thruster pulsewidth commands), and determines the forces and torques to apply to the spacecraft dynamical models. Actuator models are called from {\tt 42actuators.c:Actuators}. Like the sensor models, these models are very simple, and it's up to you to embellish them to reflect your hardware.
Actuators are the other interface between the truth model and the FSW model. An actuator model accepts commands from the FSW model (eg. wheel torque commands, or thruster pulsewidth commands), and determines the forces and torques to apply to the spacecraft dynamical models. Actuator models are called from {\tt 42actuators.c:Actuators}. Like the sensor models, these models are very simple, and it's up to you to customize them to reflect your hardware.

One actuator type requires some explanation. To enable rapid prototyping, 42 includes some ideal actuators, {\tt IdealFrc} and {\tt IdealTrq} as elements in the FSW structure. These actuators have no hardware equivalent. They give you the forces and torques you ask for, no questions asked. This is very useful for early studies. Suppose, for instance, that you want to study an orbital rendezvous and prox ops scenario. You want to exert control forces to perform prox ops, but you don't want to have to figure out your thruster layout or write up your thruster selection logic. {\tt IdealFrc} is the answer. Prototype FSW and ad hoc FSW both use {\tt IdealTrq}. As you add the hardware-based actuators into your control loop, you'll wean yourself off of the ideal actuators.
One actuator type requires some explanation. To enable rapid prototyping, 42 includes some ideal actuators, {\tt IdealFrc} and {\tt IdealTrq} as elements in the FSW structure. These actuators have no hardware equivalent. They give you the forces and torques you ask for, no questions asked. This is very useful for early studies. Suppose, for instance, that you want to study an orbital rendezvous and prox ops scenario. You want to exert control forces to perform prox ops, but you don't want to have to figure out your thruster layout or write up your thruster selection logic. {\tt IdealFrc} is the answer. Instant FSW and sandbox FSW both use {\tt IdealTrq}. As you add the hardware-based actuators into your control loop, you'll wean yourself off of the ideal actuators.

\end{document}

Expand Down
37 changes: 0 additions & 37 deletions Docs/Prototype.rtf

This file was deleted.

10 changes: 5 additions & 5 deletions Include/42.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@
#include "42defines.h"
#include "dcmkit.h"
#include "envkit.h"
#include "geomkit.h"
#include "iokit.h"
#include "mathkit.h"
#include "meshkit.h"
#include "orbkit.h"
#include "sigkit.h"
#include "sphkit.h"
Expand All @@ -52,8 +52,8 @@ EXTERN long Nsc;

/* Number of materials */
EXTERN long Nmatl;
/* Number of geometric objects */
EXTERN long Ngeom;
/* Number of geometric meshes */
EXTERN long Nmesh;

EXTERN char InOutPath[512];
EXTERN char ModelPath[512];
Expand Down Expand Up @@ -120,9 +120,9 @@ EXTERN struct SCType *SC;
/* Frm structure describes a Formation of S/C's */
EXTERN struct FormationType *Frm;

/* Geom structure manages geometric objects, used for display and */
/* Mesh structure manages geometric objects, used for display and */
/* for surface force computation (e.g. aerodynamic) */
EXTERN struct GeomType *Geom;
EXTERN struct MeshType *Mesh;

EXTERN struct POVType POV;

Expand Down
1 change: 1 addition & 0 deletions Include/42defines.h
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@
#define CMG_FSW 7
#define THR_FSW 8
#define CFS_FSW 9
#define ROVER_FSW 10

/* Command Types */
#define CMD_DIRECTION 0
Expand Down
3 changes: 1 addition & 2 deletions Include/42gl.h
Original file line number Diff line number Diff line change
Expand Up @@ -220,11 +220,10 @@ EXTERN GLfloat LightPosN[4];
EXTERN GLfloat ShadowFromNMatrix[16]; /* 4x4 Matrix transforms from N frame to Shadow Texture space */
EXTERN GLfloat CNE[9]; /* DCM between N and Eye frame */


EXTERN char Banner[120];
EXTERN GLfloat BannerColor[4];

void GeomToDisplayLists(struct GeomType *G);
void MeshToDisplayLists(struct MeshType *M);
void UpdatePOV(void);
void CamRenderExec(void);
void DrawMap(void);
Expand Down
14 changes: 7 additions & 7 deletions Include/42types.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
/* All Other Rights Reserved. */


#include "geomkit.h"
#include "meshkit.h"
#include "orbkit.h"
#include "sigkit.h"
#include "AcTypes.h"
Expand Down Expand Up @@ -112,11 +112,11 @@ struct BodyType {
double FrcN[3]; /* expressed in N */
double alpha[3]; /* Angular acceleration of B wrt N, expressed in B */
double accel[3]; /* Linear acceleration of B wrt N, expressed in N */
char GeomFileName[40];
char MeshFileName[40];
char NodeFileName[40];
char FlexFileName[40];
float ModelMatrix[16]; /* For OpenGL */
long GeomTag;
long MeshTag;
/* For KaneNBody Dynamics */
long Gin; /* Joint that B is Bout of */
double beta[3]; /* Vector from B ref pt to B[0] ref pt, expressed in N */
Expand Down Expand Up @@ -877,8 +877,8 @@ struct RegionType {
double wn[3]; /* Expressed in R frame */
double ElastCoef,DampCoef,FricCoef;
char Name[20];
char GeomFileName[40];
long GeomTag;
char MeshFileName[40];
long MeshTag;
float ModelMatrix[16]; /* For OpenGL */
};

Expand Down Expand Up @@ -926,7 +926,7 @@ struct WorldType {
long HasRing;
char Name[20];
char MapFileName[40];
char GeomFileName[40];
char MeshFileName[40];
char ColTexFileName[40];
char BumpTexFileName[40];
float Color[4];
Expand All @@ -938,7 +938,7 @@ struct WorldType {
unsigned int ColCubeTag;
unsigned int BumpCubeTag;
unsigned int CloudGlossCubeTag;
long GeomTag;
long MeshTag;
unsigned int RingTexTag;
double NearExtent,FarExtent;

Expand Down
6 changes: 3 additions & 3 deletions Kit/Include/envkit.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
#include "mathkit.h"
#include "dcmkit.h"
#include "iokit.h"
#include "geomkit.h"
#include "meshkit.h"

/*
** #ifdef __cplusplus
Expand Down Expand Up @@ -52,9 +52,9 @@ void HiFiEarthPrecNute(double JD,double C_TEME_TETE[3][3],
double C_TETE_J2000[3][3]);
void WGS84ToECEF(double glat, double glong, double alt, double p[3]);
void ECEFToWGS84(double p[3], double *glat, double *glong, double *alt);
long PolyhedronGravAcc(struct GeomType *G, double Density, double PosN[3],
long PolyhedronGravAcc(struct MeshType *M, double Density, double PosN[3],
double CWN[3][3], double GravAccN[3]);
long PolyhedronGravGrad(struct GeomType *G, double Density, double PosN[3],
long PolyhedronGravGrad(struct MeshType *M, double Density, double PosN[3],
double CWN[3][3], double GravGradN[3][3]);
void GravGradTimesInertia(double g[3][3], double I[3][3], double GGxI[3]);

Expand Down
32 changes: 16 additions & 16 deletions Kit/Include/geomkit.h → Kit/Include/meshkit.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
/* All Other Rights Reserved. */


#ifndef __GEOMKIT_H__
#define __GEOMKIT_H__
#ifndef __MESHKIT_H__
#define __MESHKIT_H__

#include <stdio.h>
#include <stdlib.h>
Expand Down Expand Up @@ -93,7 +93,7 @@ struct OctreeCellType {
long NextOnHit;
};

/* Only add an Octree to Geom struct if it'll be used */
/* Only add an Octree to Mesh struct if it'll be used */
struct OctreeType {
long Noct; /* Number of occupied cells in Octree */
long *OctIdx; /* List of indices pointing into occupied cells */
Expand All @@ -114,7 +114,7 @@ struct KDNodeType {
struct KDNodeType *HighChild;
};

struct GeomType {
struct MeshType {
char ObjFileName[40];
long Nmatl;
long Nv;
Expand Down Expand Up @@ -170,25 +170,25 @@ struct MatlType {
struct MatlType *AddMtlLib(const char *PathName, const char *MtlLibName,
struct MatlType *OldMatl, long *Nmatl);
void ScaleSpecDiffFrac(struct MatlType *Matl, long Nmatl);
void SurfaceForceProps(struct GeomType *G);
void LoadKDTree(struct GeomType *G);
long KDProjectRayOntoGeom(double Source[3], double DirVec[3],
struct GeomType *G, long *HitPoly, double HitPoint[3]);
void LoadOctree(struct GeomType *G);
long OCProjectRayOntoGeom(double Point[3],double DirVec[3],
struct GeomType *G,double ProjPoint[3],long *ClosestPoly);
struct GeomType *LoadWingsObjFile(const char *ModelPath, const char *ObjFilename,
void SurfaceForceProps(struct MeshType *M);
void LoadKDTree(struct MeshType *M);
long KDProjectRayOntoMesh(double Source[3], double DirVec[3],
struct MeshType *M, long *HitPoly, double HitPoint[3]);
void LoadOctree(struct MeshType *M);
long OCProjectRayOntoMesh(double Point[3],double DirVec[3],
struct MeshType *M,double ProjPoint[3],long *ClosestPoly);
struct MeshType *LoadWingsObjFile(const char *ModelPath, const char *ObjFilename,
struct MatlType **MatlPtr, long *Nmatl,
struct GeomType *Geom, long *Ngeom, long *GeomTag,
struct MeshType *Mesh, long *Nmesh, long *MeshTag,
long EdgesEnabled);
void WriteGeomToObjFile(struct MatlType *Matl,struct GeomType *Geom,const char *Path,
void WriteMeshToObjFile(struct MatlType *Matl,struct MeshType *Mesh,const char *Path,
const char *FileName);
double PolyhedronVolume(struct GeomType *G);
double PolyhedronVolume(struct MeshType *M);

/*
** #ifdef __cplusplus
** }
** #endif
*/

#endif /* __GEOMKIT_H__ */
#endif /* __MESHKIT_H__ */
40 changes: 20 additions & 20 deletions Kit/Source/envkit.c
Original file line number Diff line number Diff line change
Expand Up @@ -909,7 +909,7 @@ void ECEFToWGS84(double p[3], double *glat, double *glong, double *alt)
/**********************************************************************/
/* Ref Werner and Scheeres, "Exterior Gravitation of a Polyhedron ..." */
/* Returns 1 if PosN is outside polyhedron, 0 if inside */
long PolyhedronGravAcc(struct GeomType *G, double Density,
long PolyhedronGravAcc(struct MeshType *M, double Density,
double PosN[3], double CWN[3][3], double GravAccN[3])
{
struct EdgeType *E;
Expand All @@ -928,10 +928,10 @@ long PolyhedronGravAcc(struct GeomType *G, double Density,

MxV(CWN,PosN,PosW);

for(Ie=0;Ie<G->Nedge;Ie++) {
E = &G->Edge[Ie];
V1 = G->V[E->Vtx1];
V2 = G->V[E->Vtx2];
for(Ie=0;Ie<M->Nedge;Ie++) {
E = &M->Edge[Ie];
V1 = M->V[E->Vtx1];
V2 = M->V[E->Vtx2];
for(i=0;i<3;i++) {
re1[i] = V1[i] - PosW[i];
re2[i] = V2[i] - PosW[i];
Expand All @@ -945,11 +945,11 @@ long PolyhedronGravAcc(struct GeomType *G, double Density,
}
}

for(Ip=0;Ip<G->Npoly;Ip++) {
P = &G->Poly[Ip];
V1 = G->V[P->V[0]];
V2 = G->V[P->V[1]];
V3 = G->V[P->V[2]];
for(Ip=0;Ip<M->Npoly;Ip++) {
P = &M->Poly[Ip];
V1 = M->V[P->V[0]];
V2 = M->V[P->V[1]];
V3 = M->V[P->V[2]];
for(i=0;i<3;i++) {
rf1[i] = V1[i] - PosW[i];
rf2[i] = V2[i] - PosW[i];
Expand Down Expand Up @@ -984,7 +984,7 @@ long PolyhedronGravAcc(struct GeomType *G, double Density,
/**********************************************************************/
/* Ref Werner and Scheeres, "Exterior Gravitation of a Polyhedron ..." */
/* Returns 1 if PosN is outside polyhedron, 0 if inside */
long PolyhedronGravGrad(struct GeomType *G, double Density, double PosN[3],
long PolyhedronGravGrad(struct MeshType *M, double Density, double PosN[3],
double CWN[3][3], double GravGradN[3][3])
{
struct EdgeType *E;
Expand All @@ -1003,10 +1003,10 @@ long PolyhedronGravGrad(struct GeomType *G, double Density, double PosN[3],

MxV(CWN,PosN,PosW);

for(Ie=0;Ie<G->Nedge;Ie++) {
E = &G->Edge[Ie];
V1 = G->V[E->Vtx1];
V2 = G->V[E->Vtx2];
for(Ie=0;Ie<M->Nedge;Ie++) {
E = &M->Edge[Ie];
V1 = M->V[E->Vtx1];
V2 = M->V[E->Vtx2];
for(i=0;i<3;i++) {
re1[i] = V1[i] - PosW[i];
re2[i] = V2[i] - PosW[i];
Expand All @@ -1019,11 +1019,11 @@ long PolyhedronGravGrad(struct GeomType *G, double Density, double PosN[3],
}
}

for(Ip=0;Ip<G->Npoly;Ip++) {
P = &G->Poly[Ip];
V1 = G->V[P->V[0]];
V2 = G->V[P->V[1]];
V3 = G->V[P->V[2]];
for(Ip=0;Ip<M->Npoly;Ip++) {
P = &M->Poly[Ip];
V1 = M->V[P->V[0]];
V2 = M->V[P->V[1]];
V3 = M->V[P->V[2]];
for(i=0;i<3;i++) {
rf1[i] = V1[i] - PosW[i];
rf2[i] = V2[i] - PosW[i];
Expand Down
4 changes: 2 additions & 2 deletions Kit/Source/iokit.c
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ SOCKET InitSocketClient(const char *hostname, int Port,int AllowBlocking)
}
memset((char *) &Server,0,sizeof(Server));
Server.sin_family = AF_INET;
memcpy((char *)&Server.sin_addr.s_addr,(char *)Host->h_addr,
memcpy((char *)&Server.sin_addr.s_addr,(char *)Host->h_addr_list[0],
Host->h_length);
Server.sin_port = htons(Port);
printf("Client connecting to Server on Port %i\n",Port);
Expand Down Expand Up @@ -291,7 +291,7 @@ SOCKET InitSocketClient(const char *hostname, int Port,int AllowBlocking)
}
memset((char *) &Server,0,sizeof(Server));
Server.sin_family = AF_INET;
memcpy((char *)&Server.sin_addr.s_addr,(char *)Host->h_addr,
memcpy((char *)&Server.sin_addr.s_addr,(char *)Host->h_addr_list[0],
Host->h_length);
Server.sin_port = htons(Port);
printf("Client connecting to Server on Port %i\n",Port);
Expand Down
4 changes: 2 additions & 2 deletions Kit/Source/mathkit.c
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ double UNITV(double V[3])
V[2]/=A;
}
else {
printf("Attempted divide by zero in UNITV (Line %d of mathkit.c)\n",__LINE__);
printf("Attempted divide by zero in UNITV (mathkit.c:%d)\n",__LINE__);
V[0] = 0.0;
V[1] = 0.0;
V[2] = 0.0;
Expand All @@ -354,7 +354,7 @@ double CopyUnitV(double V[3], double W[3])
W[2] = V[2]/A;
}
else {
printf("Attempted divide by zero in COPYUNITV (Line %d of mathkit.c)\n",__LINE__);
printf("Attempted divide by zero in COPYUNITV (mathkit.c:%d)\n",__LINE__);
W[0] = 0.0;
W[1] = 0.0;
W[2] = 0.0;
Expand Down
Loading
Loading