Skip to content

Pi-camera UDP Client + boost MVP#326

Open
miyatakazuya wants to merge 55 commits intomainfrom
feat/pi-client
Open

Pi-camera UDP Client + boost MVP#326
miyatakazuya wants to merge 55 commits intomainfrom
feat/pi-client

Conversation

@miyatakazuya
Copy link
Contributor

@miyatakazuya miyatakazuya commented Jan 26, 2026

Closes #214 Closes #291 Closes #331

Changes

This PR introduces the MVP for the Pi-Camera Client. It includes several classes, mainly rpi.cpp/hpp and udp_client.cpp/hpp. The former implements the CameraInterface spec, and the latter implements the UDPClientInterface based off how the camera-things project sends images.

Here is a quick explanation of the request lifecycle between the obcpp RPi client and the camera-things server:

  1. Request Initiation: The client (rpi.cpp) sends a single ASCII character 'I' (Request Image) within a UDP packet to the camera-things server port.
  2. Image Capture: The server processes the request and prepares the image as raw YUV420 planes (Y, U, V).
  3. Plane Transmission (Header): For each of the three planes sequentially, the server sends a packed binary header packet over UDP. This header contains a magic number (0x12345678) for validation, the total_chunks that will follow, and the mem_size (total size of the plane in bytes).

This has shown some undterministic behavior, so looking at server for better magic number and chunking strategy.

  1. Plane Transmission (Chunks): The server then transmits the plane data split into multiple chunk packets to fit within network MTU limits (typically ~1024 bytes data chunks). Each chunk is prefixed with a 4-byte sequential chunk index in network byte order.

  2. Reconstruction: The client attempts to receive the header, validates the magic number, and reconstructs the plane by receiving the specified number of data chunks. This process is repeated for all three planes (Y, U, and V).

  3. Formatting: Once all three planes are fully received, rpi.cpp strips any padding based on specified image strides, aggregates them into a contiguous I420 buffer, and converts it to a standard OpenCV cv::Mat (BGR format) for further processing.

The RPI Client has several pre-defined behaviors to handle UDP unreliability:

  • Times out request if frames or chunks are not received after defined timeout duration.
  • Checks request magic, total chunks, and chunk size for data integrity.

On top of these additions, I've pruned deprecated PiCamera.cpp from 2024 comp which utilized gstreamer.

  • Also removed any remaining lucid mentions

Testing

The main testing solution is camera_integration_test.cpp. It allows you to test the client, assuming that the pi-client is active.

The client/server lacks unit testing, so future issues will address implementation of the udp_server as a mock pi-server for better testing.

Future Improvements

  • Add a more robust error handling and recovery mechanism
  • Add a more robust chunking mechanism
  • Add a more robust magic number strategy
  • Add a more robust timeout policy. (Some edges cases)
  • Add more configuration options for UDP IP, Port, image res, timeout, all other stuf
  • Implement Better Unit Testing

Feedback

Any feedback is appreciated, but focusing on networking constructs and testing stability.

  • Approaches on how to better maintain this type of code that is harder to test is appreciated.
  • Any other C++ standards/practices that i may have ignored.

Shouthout @smhitle and @dzodkin33 for the groundwork, and cse124 for helping me survive UDP nonsense

mountainduu and others added 30 commits January 24, 2025 18:10
added synchronous client and synchronous test server
able to serialize data in a struct and send it between client and server
can also successfully send an image, however not in the yuv420 as expected from the RPI side

sync_client_mock.cpp and sync_server_mock.cpp need to be run separately and the server needs to be started first in order for the client to successfully connect to it

currently working on converting everything into asynchronous

Asynchronous TODOS
- need to make the async client thread safe, need to learn how to use strand and such to protect shared resources and the execution context
- need to ensure that requests to take images complete in the requested order, in other words no images out of order. this isn't a problem in the synchronous version but asynchronous needs to handle it
- what do we do in the case any of the async functions fail?
- once we receive the image in yuv420 format, does it need to be reassembled by imgConvert() or is that on the cv pipeline? also need to save to local storage instead of keeping it in memory what is the expected format to save as? i.e name or title
- also need to handle errors
…red functionality. Need to further change to support the RPI functionality.
@miyatakazuya miyatakazuya changed the title Feat/pi client Draft: Pi-camera UDP Client + boost Jan 26, 2026
@miyatakazuya miyatakazuya marked this pull request as ready for review March 1, 2026 21:50
@miyatakazuya miyatakazuya changed the title Draft: Pi-camera UDP Client + boost Pi-camera UDP Client + boost MVP Mar 2, 2026
Copy link
Contributor

@AskewParity AskewParity left a comment

Choose a reason for hiding this comment

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

BIG! Thanks for doing this. I think the picam is a platform we will use for a decent while, so this not only is important for near term testing, but also will be the infrastructure for future camera stuff.

Some of the comments I left are more facetious than others. Overall, I don't have a lot of constructive comments to provide, but I have left some questions about the meaning of certain control flow statements.

Copy link
Contributor

Choose a reason for hiding this comment

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

The long term solution is to add this to the docker-file correct? If that is the case, I should start looking into implementing it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes I think we can look into using libboost-dev from the apt repository instead.

Comment on lines +22 to +26
const std::uint8_t START_REQUEST = 's';
const std::uint8_t PICTURE_REQUEST = 'I';
const std::uint8_t END_REQUEST = 'e';
const std::uint8_t LOCK_REQUEST = 'l';

Copy link
Contributor

Choose a reason for hiding this comment

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

These should be enums

Copy link
Contributor Author

Choose a reason for hiding this comment

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

will implement

Comment on lines +10 to +30
inline uint32_t IMG_WIDTH = 1456;
inline uint32_t IMG_HEIGHT = 1088;
inline uint32_t IMG_BUFFER = IMG_WIDTH * IMG_HEIGHT * 3 / 2;

// Libcamera Strides/Padding
const uint32_t STRIDE_Y = 1472;
const uint32_t STRIDE_UV = 736;

// Network Config
const char SERVER_IP[] = "192.168.77.2";
const int SERVER_PORT = 25565;

const int headerSize = 12;
const uint32_t EXPECTED_MAGIC = 0x12345678;
const size_t CHUNK_SIZE = 1024;

struct Header {
uint32_t magic;
uint32_t total_chunks;
uint32_t mem_size;
};
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this be in config?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think it depends, I can add all of these to a specific PiCamera config but it would result in a picamera-specific config that isn't used for mock or anywhere else. I plan to implement a feature where certain network intrinsics are configured on the camera-things side, and fetched via UDP instead of being hardcoded. I think for the MVP this is fine, but if you think a config is needed now I can start working on that in this PR.

@miyatakazuya
Copy link
Contributor Author

@AskewParity I've addressed the ENUM, byte order, and pruned the misc comments.
I've addressed all the comments in some form, so let me know any additional feedback

@miyatakazuya miyatakazuya requested a review from AskewParity March 3, 2026 01:23
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.

Add camera-client as a configrable camera-type Prune/Archive Picamera.cpp Raspberry Pi HQ Camera Client

6 participants