Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tracking mode #105

Open
wants to merge 55 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
89d0883
backbone of the tracking mode database
karenhaining Jun 27, 2022
e1977a1
add tracking mode to CLI
karenhaining Jun 27, 2022
74560ae
fix bug in sort
karenhaining Jun 27, 2022
52e04c0
fixed segfault with sorting stars
karenhaining Jun 27, 2022
549f32c
serializes sorted indices of stars
karenhaining Jun 30, 2022
04ebb59
added constructor for TrackingSortedDatabase
karenhaining Jul 2, 2022
8700009
added query function
karenhaining Jul 6, 2022
e6aa00b
do math with full vector instead of its components
karenhaining Jul 6, 2022
6f44b40
got rid of warning
karenhaining Jul 7, 2022
d062459
template for tracking mode added
karenhaining Jul 29, 2022
4ad6bdd
removed unnecessary function
karenhaining Jul 29, 2022
3f24f61
starting to write tracking mode algo (initial attempt)
karenhaining Aug 4, 2022
052300a
fix int16_t radius to float
karenhaining Aug 4, 2022
0cf4f54
rewriting query to make use of sorted property
karenhaining Aug 4, 2022
e0abcee
adding files to gitignore
karenhaining Aug 9, 2022
4d11776
add previous attitude class
karenhaining Aug 12, 2022
99e9c1d
add prevAttitude arg to all starid algos, set its value with command …
karenhaining Aug 12, 2022
80ea959
first try at implementing starid algorithm
karenhaining Aug 13, 2022
43bffc8
fix cli desciption, style constant name according to Google guidelines
karenhaining Aug 13, 2022
16f7108
compare vec3 equality based on threshold passed through cli
karenhaining Aug 13, 2022
0722366
second attempt at tracking starid
karenhaining Aug 14, 2022
8912d80
pipeline fixes
karenhaining Aug 14, 2022
209c14b
fix png error
karenhaining Aug 14, 2022
55ee888
fix infinite loop in query
karenhaining Aug 14, 2022
e320cc8
change rotation type from quaternion to dcm, fix bug in query
karenhaining Aug 14, 2022
b14869e
fix bug in uncertainty default value
karenhaining Aug 14, 2022
6706376
fix errors in querying
karenhaining Aug 14, 2022
fe4833e
identifies stars! (incorrectly, but at least not 0 identified)
karenhaining Aug 14, 2022
c4c3892
directly use StarIdentifer
karenhaining Aug 15, 2022
0a537ed
switch back to describing rotation with quaternions
karenhaining Aug 15, 2022
c088f80
fix database bugs
karenhaining Aug 15, 2022
5b87217
account for impossible rotations?
karenhaining Aug 15, 2022
0824c8e
fix binary search left bug
karenhaining Aug 15, 2022
bee762c
add check for not comparing the same catalog star
karenhaining Aug 15, 2022
b71ab21
small code cleanup
karenhaining Aug 16, 2022
43b8e9f
fix default value for compare threshold
karenhaining Aug 16, 2022
d789857
fixing bugs in database
karenhaining Aug 16, 2022
632647c
skip pairs that are close by, impossible rotations
karenhaining Aug 16, 2022
e252f03
angle between two vectors function in Vec3 class
karenhaining Aug 17, 2022
7c93c23
create list of stars definitely sure about
karenhaining Aug 17, 2022
e564591
no more angles
karenhaining Aug 17, 2022
119bc2e
bug fix in generated pipeline input expected stars
karenhaining Aug 18, 2022
f956e3f
working version!!!!
karenhaining Aug 18, 2022
ba76233
some code cleanup
karenhaining Aug 18, 2022
77b4198
tracking mode unit tests, clean up query
karenhaining Aug 18, 2022
8b919c2
update to cover catalog
karenhaining Aug 18, 2022
01ba8b9
fix bug in query
karenhaining Aug 19, 2022
bbe64d9
don't pass threshold as parameter, just add it directly when passing …
karenhaining Aug 19, 2022
ce74e1d
change default values for uncertainty and compare threshold
karenhaining Aug 19, 2022
40b8415
code cleanup
karenhaining Aug 19, 2022
9e16953
giant shortcut to tracking mode
karenhaining Mar 20, 2023
905103b
change default threshold values
karenhaining Mar 20, 2023
3e5cbbf
smol fix, maybe saves quite a bit of copying to/from Catalog
zeddie888 Mar 21, 2023
eb95e44
working tracking mode
karenhaining Mar 28, 2023
5291c39
Merge branch 'tracking_mode' of https://github.com/UWCubeSat/lost int…
karenhaining Mar 28, 2023
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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
*.o
*.d
*.png
*.dat
*.txt

/documentation/man-*.h

Expand Down
4 changes: 4 additions & 0 deletions documentation/database.man
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ Sets the maximum distance bin in the kvector building method to \fImax\fP (degre
\fB--kvector-distance-bins\fP \fInum-bins\fP
Sets the number of distance bins in the kvector building method to \fInum-bins\fP. Defaults to 10000 if option is not selected.

.TP
\fB--tracking\fP
Generate a Tracking mode database

.TP
\fB--output\fP \fIoutput-path\fP
The file to output the database to. Defaults to stdout.
Expand Down
16 changes: 14 additions & 2 deletions documentation/pipeline.man
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ pipeline \- builds a pipeline of the star identification process
.br
\fBpipeline\fP --generate[=\fInum-images\fP] [--horizontal-res \fIres\fP] [--vertical-res \fIres\fP] [--horizontal-fov \fIdegrees\fP] [--ref-brightness \fImag\fP] [--spread-stddev \fIstddev\fP] [--noise-stddev \fIstddev\fP] [--boresight-right-asc \fIascension\fP] [--boresight-dec \fIdeclination\fP] [--boresight-roll \fIroll\fP]
[--centroid-algo \fIalgorithm\fP [--centroid-dummy-stars \fInum-stars\fP]] [--centroid-mag-filter \fImin-mag\fP]
[--database \fIfilename\fP] [--star-id-algo \fIalgo\fP (--gv-tolerance \fIdegrees\fP | --py-tolerance \fIdegrees\fP --false-stars \fInum\fP --max-mismatch-prob \fIprobability\fP)] [--attitude-algo \fIalgo\fP] [--plot \fIoutput-path\fB]
[--database \fIfilename\fP] [--star-id-algo \fIalgo\fP (--gv-tolerance \fIdegrees\fP | --py-tolerance \fIdegrees\fP --false-stars \fInum\fP --max-mismatch-prob \fIprobability\fP | --prev-attitude \fIattitude\fP --uncertainty \fIradius\fP (--tracking-compare-threshold \fIthreshold\fP))] [--attitude-algo \fIalgo\fP] [--plot \fIoutput-path\fB]

.SH DESCRIPTION

Expand Down Expand Up @@ -55,7 +55,7 @@ Will not consider candidate as centroid if its magnitude is below \fImin-mag\fP.

.TP
\fB--star-id-algo\fP \fIalgo\fP
Runs the \fIalgo\fP star identification algorithm. Current options are "dummy", "gv", and "pyramid". Defaults to "dummy" if option is not selected.
Runs the \fIalgo\fP star identification algorithm. Current options are "dummy", "gv", "pyramid", and "tracking". Defaults to "pyramid" if option is not selected.

.TP
\fB--angular-tolerance\fP [\fItolerance\fP] Sets the estimated angular centroiding error tolerance,
Expand All @@ -69,6 +69,18 @@ used in some star id algorithms, to \fItolerance\fP degrees. Defaults to 0.04 de
\fB--max-mismatch-prob\fP \fIprobability\fP
\fIprobability\fP is the maximum allowable probability of an incorrect star identification, for star id algorithms which support it. Defaults to 0.001.

.TP
\fB--prev-attitude\fP \fIattitude\fP
\fIattitude\fP is the known previous attitude for tracking mode. Should give ra, dec, and roll as a comma-separated list: "ra,dec,roll."

.TP
\fB--uncertainty\fP \fIradius\fP
For tracking mode. \fIradius\fP gives the boundary for how much the field of view could have rotated. Defaults to 0.001 if not selected. Must be nonnegative.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are the units? Degrees, pixels?

Also, the name is too short, the cli option name should make it clear that it's talking about uncertainty in the previous attitude.


.TP
\fB--tracking-compare-threshold\fP \fIthreshold\fP
\fIthreshold\fP is the threshold for comparing floats for tracking mode. Defaults to 0.001 if no value is given.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are the units? What exactly is being compared?


.TP
\fB--attitude-algo\fP \fIalgo\fP
Runs the \fIalgo\fP algorithm for the attitude stage of the pipeline. Current options are "dqm" (Davenport Q) and "triad". Defaults to dqm.
Expand Down
1 change: 1 addition & 0 deletions src/database-options.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ LOST_CLI_OPTION("kvector" , bool , kvector , fa
LOST_CLI_OPTION("kvector-min-distance" , float , kvectorMinDistance , 0.5 , atof(optarg) , kNoDefaultArgument)
LOST_CLI_OPTION("kvector-max-distance" , float , kvectorMaxDistance , 15 , atof(optarg) , kNoDefaultArgument)
LOST_CLI_OPTION("kvector-distance-bins", long , kvectorNumDistanceBins, 10000 , atol(optarg) , kNoDefaultArgument)
LOST_CLI_OPTION("tracking" , bool , tracking , false , atobool(optarg), true)
LOST_CLI_OPTION("output" , std::string, outputPath , "-" , optarg , kNoDefaultArgument)
120 changes: 119 additions & 1 deletion src/databases.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ void SerializePairDistanceKVector(const Catalog &catalog, float minDistance, flo

PairDistanceKVectorDatabase::PairDistanceKVectorDatabase(const unsigned char *buffer)
: index(KVectorIndex(buffer)) {

// TODO: errors? (not even sure what i meant by this comment anymore)
buffer += SerializeLengthKVectorIndex(index.NumBins());
pairs = (const int16_t *)buffer;
Expand Down Expand Up @@ -314,6 +314,124 @@ MultiDatabaseBuilder::~MultiDatabaseBuilder() {
free(buffer);
}


/*** for tracking mode ***/

// to associate stars with a definite index in the catalog
struct TrackingStar {
int16_t index;
CatalogStar star;
};

// length of the serialized tracking catalog
long SerializeLengthTrackingCatalog(const Catalog &catalog) {
return (catalog.size()+1) * sizeof(int16_t);
}

// comparator for ordering stars in tracking database
bool CompareTrackingStars(const TrackingStar &s1, const TrackingStar &s2) {
return s1.star.spatial.x < s2.star.spatial.x;
}

// serialize tracking catalog (length of catalog, then list of indices into catalog sorted by x-coordinate of stars)
void SerializeTrackingCatalog(const Catalog &catalog, unsigned char *buffer) {
std::vector<TrackingStar> stars;

for (long unsigned int i = 0; i < catalog.size(); i++) {
TrackingStar s;
s.index = i;
s.star = catalog.at(i);
stars.push_back(s);
}

std::sort(stars.begin(), stars.end(), CompareTrackingStars);

// serialize into buffer
unsigned char *bufferStart = buffer;

// store length of catalog into the buffer
*(int16_t *)buffer = catalog.size();
buffer += sizeof(int16_t);

// store the sorted list of indices into the buffer
for (const TrackingStar &star : stars) {
*(int16_t *)buffer = star.index;
buffer += sizeof(int16_t);
}

// verify length
assert(buffer - bufferStart == SerializeLengthTrackingCatalog(catalog));
}

// deserialize database
TrackingSortedDatabase::TrackingSortedDatabase(const unsigned char *buffer) {

length = *(int16_t *)buffer;
buffer += sizeof(int16_t);

for (int i = 0; i < length; i++) {
int16_t index = *(int16_t *)buffer;
buffer += sizeof(int16_t);
indices.push_back(index);
}
}

// query database (returns list of indices into the catalog that have stars within radius of point)
std::vector<int16_t> TrackingSortedDatabase::QueryNearestStars(const Catalog& catalog, const Vec3 point, float radius) {
assert(radius >= 0);

std::vector<int16_t> query_ind;

// binary search to find an initial element with x-element in right range
int16_t left = 0;
int16_t right = length-1;
int16_t index = -1;

while (left <= right) {
int16_t mid = left + (right - left) / 2;
CatalogStar s = catalog[indices[mid]];
Vec3 diff = s.spatial - point;
if (abs(diff.x) <= radius) {
index = mid;
break;
} else if (s.spatial.x < point.x) {
left = mid + 1;
} else {
right = mid - 1;
}
}

// now see which other stars are within radius
left = index;
right = index+1;

// see how far left you can go
CatalogStar sLeft = catalog[indices[left]];
Vec3 diffLeft = sLeft.spatial - point;
while (left >= 0 && (abs(diffLeft.x) <= radius)) {
if (diffLeft.Magnitude() <= radius) {
query_ind.push_back(indices[left]);
}
left--;
sLeft = catalog[indices[left]];
diffLeft = sLeft.spatial - point;
}

// see how far right you can go
CatalogStar sRight = catalog[indices[right]];
Vec3 diffRight = sRight.spatial - point;
while (right < length && (abs(diffRight.x) <= radius)) {
if (diffRight.Magnitude() <= radius) {
query_ind.push_back(indices[right]);
}
right++;
sRight = catalog[indices[right]];
diffRight = sRight.spatial - point;
}

return query_ind;
}

}

// TODO: after creating the database, print more statistics, such as average number of pairs per
Expand Down
17 changes: 17 additions & 0 deletions src/databases.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,23 @@ class TripleInnerKVectorDatabase {
int16_t *triples;
};



// tracking mode database (basically stars are sorted by vector spatial x coord)
class TrackingSortedDatabase {
public:
TrackingSortedDatabase(const unsigned char *databaseBytes);
const static int32_t kMagicValue = 0x2536f0A9;
std::vector<int16_t> QueryNearestStars(const Catalog &, const Vec3 point, float radius);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should have short documentation comment in header file


private:
int16_t length; // length of catalog
std::vector<int16_t> indices; // sorted list of catalog indices
};

long SerializeLengthTrackingCatalog(const Catalog &catalog);
void SerializeTrackingCatalog(const Catalog &catalog, unsigned char *buffer);

// maximum number of databases in a MultiDatabase
const int kMultiDatabaseMaxDatabases = 64;
const long kMultiDatabaseTocLength = 8*kMultiDatabaseMaxDatabases;
Expand Down
36 changes: 34 additions & 2 deletions src/io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,15 @@ void BuildKVectorDatabase(MultiDatabaseBuilder &builder, const Catalog &catalog,

}

void BuildTrackingDatabase(MultiDatabaseBuilder &builder, const Catalog &catalog) {
long length = SerializeLengthTrackingCatalog(catalog);
unsigned char *buffer = builder.AddSubDatabase(TrackingSortedDatabase::kMagicValue, length);
if (buffer == NULL) {
std::cerr << "No room for another database." << std::endl;
}
SerializeTrackingCatalog(catalog, buffer);
}


void GenerateDatabases(MultiDatabaseBuilder &builder, const Catalog &catalog, const DatabaseOptions &values) {

Expand All @@ -257,6 +266,8 @@ void GenerateDatabases(MultiDatabaseBuilder &builder, const Catalog &catalog, co
float maxDistance = DegToRad(values.kvectorMaxDistance);
long numBins = values.kvectorNumDistanceBins;
BuildKVectorDatabase(builder, catalog, minDistance, maxDistance, numBins);
} else if (values.tracking) {
BuildTrackingDatabase(builder, catalog);
} else {
std::cerr << "No database builder selected -- no database generated." << std::endl;
exit(1);
Expand Down Expand Up @@ -473,8 +484,8 @@ GeneratedPipelineInput::GeneratedPipelineInput(const Catalog &catalog,

// don't add false stars to centroids or star ids
if (isTrueStar) {
starIds.push_back(StarIdentifier(stars.size() - 1, i));
stars.push_back(star);
starIds.push_back(StarIdentifier(stars.size() - 1, i));
}
}
}
Expand Down Expand Up @@ -684,6 +695,28 @@ Pipeline SetPipeline(const PipelineOptions &values) {
result.starIdAlgorithm = std::unique_ptr<StarIdAlgorithm>(new GeometricVotingStarIdAlgorithm(DegToRad(values.angularTolerance)));
} else if (values.idAlgo == "py") {
result.starIdAlgorithm = std::unique_ptr<StarIdAlgorithm>(new PyramidStarIdAlgorithm(DegToRad(values.angularTolerance), values.estimatedNumFalseStars, values.maxMismatchProb, 1000));
} else if (values.idAlgo == "tracking") {

if (values.prevAttitudeString == "") {
std::cout << "WARNING: information about the previous attitude has not been passed in while tracking mode is set." << std::endl;
}

// convert user inputted string ra,dec,roll to individual floats
std::vector<float> attInputs;
std::stringstream ss (values.prevAttitudeString);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Taking attitude input as a single comma-separated string is a good idea, but we need to apply it consistently across the codebase. If we're going to do it here, we also need to replace the --generate-ra, --generate-de, and --generate-roll options with a single combined option (and there should be a separate function for parsing comma-separated attitudes, in attitude-utils.cpp)

std::string item;
while (std::getline (ss, item, ',')) {
attInputs.push_back(stof(item));
}

// convert ra, dec, and roll to attitude
Quaternion q = SphericalToQuaternion(DegToRad(attInputs[0]), DegToRad(attInputs[1]), DegToRad(attInputs[2]));
Attitude a(q);

// set prev attitude and id algo
PrevAttitude prev(a, values.uncertainty, values.trackingCompareThreshold);
result.starIdAlgorithm = std::unique_ptr<StarIdAlgorithm>(new TrackingModeStarIdAlgorithm(prev));

} else if (values.idAlgo != "") {
std::cout << "Illegal id algorithm." << std::endl;
exit(1);
Expand Down Expand Up @@ -762,7 +795,6 @@ PipelineOutput Pipeline::Go(const PipelineInput &input) {
std::vector<PipelineOutput> Pipeline::Go(const PipelineInputList &inputs) {
std::vector<PipelineOutput> result;


for (const std::unique_ptr<PipelineInput> &input : inputs) {
result.push_back(Go(*input));
}
Expand Down
5 changes: 4 additions & 1 deletion src/pipeline-options.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
// Inside of the current Paragraph to comma.

// CAMERA
LOST_CLI_OPTION("png" , std::string, png , "" , atof(optarg) , kNoDefaultArgument)
LOST_CLI_OPTION("png" , std::string, png , "" , optarg, kNoDefaultArgument)
LOST_CLI_OPTION("focal-length" , float , focalLength , 0 , atof(optarg) , kNoDefaultArgument)
LOST_CLI_OPTION("pixel-size" , float , pixelSize , -1 , atof(optarg) , kNoDefaultArgument)
LOST_CLI_OPTION("fov" , float , fov , 20 , atof(optarg) , kNoDefaultArgument)
Expand All @@ -24,6 +24,9 @@ LOST_CLI_OPTION("centroid-dummy-stars" , int , centroidDummyNumStars
LOST_CLI_OPTION("centroid-mag-filter" , float , centroidMagFilter , -1 , atof(optarg) , 5)
LOST_CLI_OPTION("database" , std::string, databasePath , "" , optarg , kNoDefaultArgument)
LOST_CLI_OPTION("star-id-algo" , std::string, idAlgo , "" , optarg , "pyramid")
LOST_CLI_OPTION("prev-attitude" , std::string, prevAttitudeString , "" , optarg , kNoDefaultArgument)
LOST_CLI_OPTION("uncertainty " , float , uncertainty , 0.001 , atof(optarg) , kNoDefaultArgument)
LOST_CLI_OPTION("tracking-compare-threshold", float , trackingCompareThreshold, 0.001 , atof(optarg) , kNoDefaultArgument)
LOST_CLI_OPTION("angular-tolerance" , float , angularTolerance , .04 , atof(optarg) , kNoDefaultArgument)
LOST_CLI_OPTION("false-stars-estimate" , int , estimatedNumFalseStars , 500 , atoi(optarg) , kNoDefaultArgument)
LOST_CLI_OPTION("max-mismatch-probability" , float , maxMismatchProb , .001, atof(optarg) , kNoDefaultArgument)
Expand Down
36 changes: 35 additions & 1 deletion src/star-id.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
#include <math.h>
#include <assert.h>
#include <vector>
#include <algorithm>
#include <map>

#include "star-id.hpp"
#include "databases.hpp"
Expand Down Expand Up @@ -489,7 +491,6 @@ StarIdentifiers PyramidStarIdAlgorithm::Go(

PyramidIdentifyRemainingStars(&identified, stars, catalog, vectorDatabase, camera, tolerance);
printf("Identified an additional %d stars\n", (int)identified.size() - 4);

return identified;
}

Expand All @@ -503,4 +504,37 @@ StarIdentifiers PyramidStarIdAlgorithm::Go(
return identified;
}

// for ordering Quaternions in tracking mode votes map
bool operator<(const Quaternion& l, const Quaternion& r) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not an appropriate general-purpose comparison for quaternions, just write it as a separate function and pass as a custom comparator to std::sort

Also, || is your friend.

if (l.real < r.real) return true;
if (l.i < r.i) return true;
if (l.j < r.j) return true;
return (l.k < r.k);
}

StarIdentifiers TrackingModeStarIdAlgorithm::Go(
const unsigned char *database, const Stars &stars, const Catalog &catalog, const Camera &camera) const {

StarIdentifiers definite;
MultiDatabase multiDatabase(database);
const unsigned char *databaseBuffer = multiDatabase.SubDatabasePointer(TrackingSortedDatabase::kMagicValue);
if (databaseBuffer == NULL) {
return definite;
}
TrackingSortedDatabase vectorDatabase(databaseBuffer);

// find all stars that only have 1 possible previous star, so we've definitely id'd them
for (int i = 0; i < (int)stars.size(); i++) {
Vec3 prevPos = camera.CameraToSpatial(stars[i].position).Normalize();
prevPos = prevAttitude.prev.GetQuaternion().Conjugate().Rotate(prevPos);

std::vector<int16_t> possiblePrevStars = vectorDatabase.QueryNearestStars(catalog, prevPos, prevAttitude.uncertainty+prevAttitude.compareThreshold);
if (possiblePrevStars.size() == 1) {
definite.push_back(StarIdentifier(i,possiblePrevStars[0]));
}
}

return definite;
}

}
Loading