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

CV Pipeline Integration #73

Merged
merged 82 commits into from
Apr 2, 2024
Merged

CV Pipeline Integration #73

merged 82 commits into from
Apr 2, 2024

Conversation

atar13
Copy link
Member

@atar13 atar13 commented Jan 5, 2024

Closes #62
Closes #30

Changes

Set up a skeleton of the Computer Vision pipeline. This includes classes and function signatures for all modules of the pipeline. Now, the types of output data of each stage of the pipeline is well defined.

Also created a SearchState class that inherits from MissionState. In its tick function it starts up a new thread that captures a new image from the camera and passes it into the pipeline. I have not implemented any way to collect results from multiple threads, send the results to the GCS, or shut down threads that exceed a timeout. These should be done in a later PR.

This PR also includes a MockCamera implementation that implements CameraInterface. I just added it to easily be able to fetch dummy image data. Right now it just returns an image with a solid color but in the future it should return an image with valid competition targets.

Testing

There's a small unit test to test an image crop helper function. tests/unit/cv/utilities_test.cpp

There's another unit test to test the mock camera test/unit/camera/mock.cpp

There's an integration test to allow someone to run the entire CV pipeline using an arbitrary image from a filepath. tests/integration/pipeline.cpp

Feedback

Any feedback is appreciated, but I'd like to focus on a few specific parts.

@atar13
Copy link
Member Author

atar13 commented Jan 5, 2024

Going to also ping @dzodkin33 since I touched some of the CameraInterface code to get the MockCamera up and running.

Also want to ping @hashreds and @cr1t1cql since they will be filling in some of the modules of the pipeline.

@atar13 atar13 self-assigned this Jan 5, 2024
atar13 and others added 9 commits January 15, 2024 03:47
empty classes/methods for CV pipeline. this commit will define the types
and layout of inputs/outputs of each stage of the pipeline.

includes the following modules:
- saliency
- localization
- matching
- segmentation
- classification

also added some additional data to ImageData that will be needed for
pipeline.
right now only testing crop function
implements two methods of CameraInterface to quickly plug in something
to the rest of the pipeline. For now it just generates an image of a
solid color. In the future we could have it return an actual competition
image with a valid target that the models can recognize.

set up other CameraInterface related functions to get MockCamera working
set up tick method that captures a photo and passes it through the CV
pipeline in a new thread
integration test to allow for portable testing of the entire CV pipeline
using an arbitrary image as input
to match other unit test files
@Samir-Rashid
Copy link
Contributor

I have rebased and gotten the ✅ on the commit.

I have not implemented any way to...shut down threads that exceed a timeout.

I have run into this in other places in this project. I think we should make a reusable way to add this functionality.

Copy link
Contributor

@Samir-Rashid Samir-Rashid left a comment

Choose a reason for hiding this comment

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

Amazing job, Anthony. This is an extremely well made mega-PR that was a delight to review. I really liked the long-form comments you included explaining the different parts of the system. Your additions look good and are an important step to bringing the structure of remaining work into definition. I think this design allows for a good amount of wiggle room as the implementations find things that need to be changed.


#include <nlohmann/json.hpp>
#include <opencv2/opencv.hpp>

// class to contain all telemetry that should be tagged with an image.
// In the future this could be in a mavlink file.
Copy link
Contributor

Choose a reason for hiding this comment

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

What is a mavlink file

Copy link
Member Author

Choose a reason for hiding this comment

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

I was thinking of a mavlink.hpp that would be added by Jasper in his Mavlink Client.

// In the future this could be in a mavlink file.
class ImageTelemetry {
public:
ImageTelemetry(double latitude, double longitude, double altitude, double airspeed, double yaw,
Copy link
Contributor

Choose a reason for hiding this comment

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

This could use the GPSCoord type. I like how you made a ImageTelemetry type so it is easy to add/remove fields in the future. I think it is more conventional to make this a struct since everything is public. Also this should have a default initializer {} for all the values.

Copy link
Member Author

@atar13 atar13 Jan 17, 2024

Choose a reason for hiding this comment

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

I like the idea of removing some of the fields in favor of GPSCoord. I have also changed ImageTelemetry to a struct.

What do you mean by default initializer? Is that the same as the constructor implementation in camera/interface.cpp? https://github.com/tritonuas/obcpp/blob/feat/cv-orchestrator/src/camera/interface.cpp#L3-L11

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, that will make sure this all gets zero initialized.

@@ -50,8 +69,8 @@ class CameraConfiguration {
class CameraInterface {
private:
CameraConfiguration config;
ImageData recentPicture; // might need to move it to public
bool doneTakingPicture; // overengineering time
std::unique_ptr<ImageData> recentPicture; // might need to move it to public
Copy link
Contributor

Choose a reason for hiding this comment

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

Well at least it should be fine if it's private ...because the smart pointer is handling all the scoping memory for us.

// overengineering time

🤔 I cannot give useful advice on the design of this interface ...because I have no idea what kinds of functionality we have been using in the past since '87. I do not want to block based on any minor improvements, so as long as you are happy with this we should forge ahead. That being said, it would be good to reping the people in your comment to get a better set of eyes.

Copy link
Member Author

Choose a reason for hiding this comment

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

I should have removed that public comment. That was made by Boris in the original interface. And so was the over engineering comment. This PR wasn't supposed to drastically change the camera interface but we've already had a design talk with Boris during the meeting on how to simplify the API.

*/
class SearchState : public MissionState {
public:
// Passing in a unique_ptr to a CameraInterface for dependency
Copy link
Contributor

Choose a reason for hiding this comment

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

I think your mocking approach is fine.

struct PipelineResults {
ImageData imageData;
std::vector<AirdropTarget> matchedTargets;
// Not sure if unmatchedTargets should hold a different struct than
Copy link
Contributor

Choose a reason for hiding this comment

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

For sure both should be the same type

// Just thinking out loud regarding thread saftey here. With the code below,
// we will be capturing a new image from the camera and running it through
// the models of the CV pipeline once on every tick (every second or so).
// In terms of potential data races here are a few I can think of:
Copy link
Contributor

Choose a reason for hiding this comment

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

Simply design your system to be impossible to have data races and then put it in the appendix.

// TODO: send to GCS for verification
});

// TODO: Need a way to cleanup any running threads when the state changes
Copy link
Contributor

Choose a reason for hiding this comment

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

This is a good point worth emphasizing. I think we can use a smart pointer for the state which will automatically call destructors for each state when needed.

Copy link
Contributor

Choose a reason for hiding this comment

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

Actually Tyler already brought up these concerns here #55 (comment)

tests/integration/cv_pipeline.cpp Show resolved Hide resolved
tests/unit/camera/mock.cpp Show resolved Hide resolved
tests/unit/cv/utilities_test.cpp Outdated Show resolved Hide resolved
@atar13
Copy link
Member Author

atar13 commented Jan 17, 2024

I have rebased and gotten the ✅ on the commit.

I have not implemented any way to...shut down threads that exceed a timeout.

I have run into this in other places in this project. I think we should make a reusable way to add this functionality.

Thank you for getting the lint up to spec. Much appreciated.

@atar13 atar13 marked this pull request as draft February 15, 2024 21:35
* update ubuntu version 🙏

* fix groupadd command
* update ubuntu version 🙏

* fix groupadd command

* fix error
* update ubuntu version 🙏

* fix groupadd command

* fix error

* fix typo
* update ubuntu version 🙏

* fix groupadd command

* fix error

* fix typo

* WHY THE FUCK DID IT NOT MERGE THIS IN?
* update ubuntu version 🙏

* fix groupadd command

* fix error

* fix typo

* WHY THE FUCK DID IT NOT MERGE THIS IN?

* install cpplint through apt instead of pip3
* update ubuntu version 🙏

* fix groupadd command

* fix error

* fix typo

* WHY THE FUCK DID IT NOT MERGE THIS IN?

* install cpplint through apt instead of pip3

* try to fix user id
* update ubuntu version 🙏

* fix groupadd command

* fix error

* fix typo

* WHY THE FUCK DID IT NOT MERGE THIS IN?

* install cpplint through apt instead of pip3

* try to fix user id

* i am at my wits end 🔫
* update ubuntu version 🙏

* fix groupadd command

* fix error

* fix typo

* WHY THE FUCK DID IT NOT MERGE THIS IN?

* install cpplint through apt instead of pip3

* try to fix user id

* i am at my wits end 🔫

* fix dumbass merge conflict
* update ubuntu version 🙏

* fix groupadd command

* fix error

* fix typo

* WHY THE FUCK DID IT NOT MERGE THIS IN?

* install cpplint through apt instead of pip3

* try to fix user id

* i am at my wits end 🔫

* fix dumbass merge conflict

* fix this bullshit
@atar13 atar13 marked this pull request as ready for review March 29, 2024 05:53
Copy link
Contributor

@Tyler-Lentz Tyler-Lentz left a comment

Choose a reason for hiding this comment

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

The cv_pipeline integration tests looks like it is failing to compile for me:

/workspaces/obcpp/tests/integration/cv_pipeline.cpp: In function 'int main()':
/workspaces/obcpp/tests/integration/cv_pipeline.cpp:80:53: error: no matching function for call to 'Pipeline::Pipeline(std::array<Bottle, 5>&, std::vector<std::pair<cv::Mat, unsigned char> >&)'
   80 |     Pipeline pipeline(bottlesToDrop, referenceImages);
      |                                                     ^
In file included from /workspaces/obcpp/tests/integration/cv_pipeline.cpp:5:
/workspaces/obcpp/include/cv/pipeline.hpp:35:9: note: candidate: 'Pipeline::Pipeline(std::array<Bottle, 5>, std::vector<std::pair<cv::Mat, BottleDropIndex> >)'
   35 |         Pipeline(std::array<Bottle, NUM_AIRDROP_BOTTLES> competitionObjectives,
      |         ^~~~~~~~
/workspaces/obcpp/include/cv/pipeline.hpp:36:62: note:   no known conversion for argument 2 from 'vector<pair<[...],unsigned char>>' to 'vector<pair<[...],BottleDropIndex>>'
   36 |             std::vector<std::pair<cv::Mat, BottleDropIndex>> referenceImages);
      |             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~
/workspaces/obcpp/include/cv/pipeline.hpp:33:7: note: candidate: 'Pipeline::Pipeline(const Pipeline&)'
   33 | class Pipeline {
      |       ^~~~~~~~
/workspaces/obcpp/include/cv/pipeline.hpp:33:7: note:   candidate expects 1 argument, 2 provided
/workspaces/obcpp/include/cv/pipeline.hpp:33:7: note: candidate: 'Pipeline::Pipeline(Pipeline&&)'
/workspaces/obcpp/include/cv/pipeline.hpp:33:7: note:   candidate expects 1 argument, 2 provided
make[3]: *** [CMakeFiles/cv_pipeline.dir/build.make:496: CMakeFiles/cv_pipeline.dir/tests/integration/cv_pipeline.cpp.o] Error 1
make[2]: *** [CMakeFiles/Makefile2:421: CMakeFiles/cv_pipeline.dir/all] Error 2
make[1]: *** [CMakeFiles/Makefile2:428: CMakeFiles/cv_pipeline.dir/rule] Error 2
make: *** [Makefile:221: cv_pipeline] Error 2

Also, it would be good to change all of the couts and cerrs through the cv code to use the logging library instead.

I like the general structure of the CV stuff though. It should be easy to slot everything in where they need to go.

@atar13 atar13 changed the title Skeleton CV pipeline and SearchState tick CV Pipeline Integration Mar 31, 2024
@atar13
Copy link
Member Author

atar13 commented Mar 31, 2024

cv_pipeline should compile now. We moved some stuff to use some of the protobuf structs but forgot to update it in the cv_pipeline test.

Before this gets merged in I want to

  • verify all the new integration tests compile
  • add links to download testing models/images
  • move cout/cerrs logging library
  • add comments to unit tests

@shijiew555 and @hashreds can merge in their changes to main for classification and saliency respectively. We want to get this branch merged in as soon as possible so that other branches can depend on the existing changes.

atar13 added 7 commits April 1, 2024 22:39
also added some comments for some of the cv test files
also removed some hardcoded model paths and moved them to constructors
we need to debug the ECEF localization algorithm but it's out of the
scope of the feat/cv-orchestrator PR and I want a green checkmark
@atar13 atar13 requested a review from Tyler-Lentz April 1, 2024 23:38
Copy link
Contributor

@Tyler-Lentz Tyler-Lentz left a comment

Choose a reason for hiding this comment

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

I really like all of the code structure and organization for everything. I had the issue with the image paths, but I think that's just a me issue and I don't think its worth holding up the merge over it. Once we automate the asset pulling process fully we can rigorously test to make sure everything is robust.

@atar13 atar13 merged commit 8e07698 into main Apr 2, 2024
2 checks passed
@atar13 atar13 deleted the feat/cv-orchestrator branch April 2, 2024 22:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Set up orchestrator for CV pipeline Camera Connection Mock
6 participants