Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
864111e
started on the rpi interface
mountainduu Jan 25, 2025
078eae9
[LIB] add boost
dzodkin33 Jan 29, 2025
c733592
[ADD] some basic socket design ideas
dzodkin33 Jan 29, 2025
f94e54a
hold
dzodkin33 Feb 6, 2025
d55398d
[ADD] TCP interfaces, data structs
dzodkin33 Feb 25, 2025
efe4aa1
[add] implementation files
dzodkin33 Feb 25, 2025
9d082df
[ADD] changed headers, constr and connect funcs in cpp
dzodkin33 Feb 28, 2025
8f7530f
[ADD] basic client + send function
dzodkin33 Mar 7, 2025
7d65cf6
TCP Client and Server
smhitle Apr 15, 2025
bcfdaa0
merge main
AskewParity Apr 18, 2025
6e3b256
change boost import
AskewParity Apr 18, 2025
cb845f6
added VERY INEFFICIENT way to make serialization to work
AskewParity Apr 18, 2025
a396fa6
Changes to the client. Modified interface.hpp/.cpp to match the requi…
smhitle May 6, 2025
83e9ef6
chore: remove boost:serialization
AskewParity May 7, 2025
00d6adf
Undid changes to interface.cpp. Provided skeleton code, now compiles
smhitle May 8, 2025
7548cfb
Prototypal code for the entire process
smhitle May 9, 2025
2a3b163
Testing on jetson
smhitle May 9, 2025
d5a7adf
Added log statements for debugging
smhitle May 9, 2025
d573496
Added a mock rpi server
smhitle May 9, 2025
0d12b7f
Deleted unused files, switched to UDP instead of TCP
smhitle May 15, 2025
6c68c3f
Added server mock stuff
smhitle May 16, 2025
4121c05
Changed cout's to LOG_F's
smhitle May 18, 2025
b8eb719
Can read in udp packets correctly (hopefully)
smhitle May 22, 2025
4d3f717
Updated mock udp server
smhitle May 25, 2025
6f78c76
Updated cmake for server mock
smhitle May 25, 2025
19cacc7
Mock server works for dev container purposes
smhitle May 25, 2025
b1ba268
Merge remote-tracking branch 'origin' into dev/camera/tcp-socket/tyler
AskewParity Nov 9, 2025
a9f90d7
chore: update integration/cmake
AskewParity Nov 9, 2025
d0d76d4
fix: mock camera (merge incorrect)
AskewParity Nov 9, 2025
98d302a
fix: linking issue for camera and mavlink
AskewParity Nov 14, 2025
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
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ include(${DEPS_DIRECTORY}/matplot/matplot.cmake)
include(${DEPS_DIRECTORY}/protobuf/protobuf.cmake)
include(${DEPS_DIRECTORY}/loguru/loguru.cmake)
include(${DEPS_DIRECTORY}/imagemagick/imagemagick.cmake)
include(${DEPS_DIRECTORY}/boost/boost.cmake)
# =============================

# =============================
Expand Down
16 changes: 16 additions & 0 deletions deps/boost/boost.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
function(target_add_boost target_name)
include(FetchContent)

FetchContent_Declare(boost
URL https://github.com/boostorg/boost/releases/download/boost-1.87.0/boost-1.87.0-b2-nodocs.tar.gz
URL_HASH SHA256=d6c69e4459eb5d6ec208250291221e7ff4a2affde9af6e49c9303b89c687461f
DOWNLOAD_EXTRACT_TIMESTAMP true
)
FetchContent_MakeAvailable(boost)
# target_link_libraries(${target_name} PRIVATE
# boost
# )
target_include_directories(${target_name} PRIVATE ${boost_SOURCE_DIR})


endfunction()
2 changes: 1 addition & 1 deletion include/camera/interface.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,4 +101,4 @@ class CameraInterface {
std::shared_ptr<MavlinkClient> mavlinkClient) = 0;
};

#endif // INCLUDE_CAMERA_INTERFACE_HPP_
#endif // INCLUDE_CAMERA_INTERFACE_HPP_
88 changes: 88 additions & 0 deletions include/camera/rpi.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#ifndef INCLUDE_CAMERA_RPI_HPP_
#define INCLUDE_CAMERA_RPI_HPP_


#include <string>
#include <memory>
#include <optional>
#include <shared_mutex>
#include <thread>
#include <deque>

#include <nlohmann/json.hpp>

#include "camera/interface.hpp"
#include "network/mavlink.hpp"

using json = nlohmann::json;

using namespace std::chrono_literals; // NOLINT

#include "interface.hpp"
#include "network/udp_client.hpp"

namespace asio = boost::asio;

// const std::string SERVER_IP = "192.168.68.1";
// const int SERVER_PORT = 25565;
// const std::string SERVER_IP = "127.0.0.1";
// const int SERVER_PORT = 5000;
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';

class RPICamera : public CameraInterface {
private:
UDPClient client;
asio::io_context io_context_;

std::atomic_bool connected;

std::deque<ImageData> imageQueue; // TODO: unsure if we actually need this if we're just gonna directly save images to disk

// lock for obc client?
// lock for imageQueue?

/**
* Converts the image taken from the camera to a suitable format for the CV pipeline
*/
std::optional<cv::Mat> imgConvert(std::vector<std::uint8_t> imgbuf);

/**
* Reads in the image data when taking a picture
*/
std::vector<std::uint8_t> readImage();

/**
* Reads in the telemetry data when taking a picture
*/
std::optional<ImageTelemetry> readTelemetry();

std::vector<std::uint8_t> readPacket();

public:

explicit RPICamera(CameraConfig config, asio::io_context* io_context_);

// TODO: destructor?
~RPICamera();

void connect() override;
bool isConnected() override;

std::optional<ImageData> getLatestImage() override {return std::nullopt;}
std::deque<ImageData> getAllImages() override {return std::deque<ImageData>();}
std::optional<ImageData> takePicture(const std::chrono::milliseconds& timeout, std::shared_ptr<MavlinkClient> mavlinkClient) override;

void startTakingPictures(const std::chrono::milliseconds& interval,
std::shared_ptr<MavlinkClient> mavlinkClient) override;
void stopTakingPictures() override;

void startStreaming() override;

// TODO: unsure how to implement
void ping();
};

#endif
82 changes: 82 additions & 0 deletions include/network/camera_data.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#ifndef INCLUDE_NETWORK_CAMERA_DATA_HPP_
#define INCLUDE_NETWORK_CAMERA_DATA_HPP_

#include <iostream>
#include <boost/serialization/serialization.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>

struct ImageData_t
{
int width;
int height;
size_t imageSizeBytes;
std::vector<std::uint8_t> imgBuffer;

template<class Archive>
void serialize(Archive & ar, const unsigned int version){
ar & width;
ar & height;
ar & imageSizeBytes;
ar & imgBuffer;
}
};

// What does OBC needs from camera
enum class RequestType_t
{
SENDIMAGE
};

// TODO: unsure if these need to be in a namespace or not
template<class Archive>
void serialize(Archive & ar, RequestType_t & request, const unsigned int version) {
ar & static_cast<int>(request); // have to type cast enum class
}

// What is the status of the request (debugging + error handling)
enum class ResponseType_t
{
SUCC,
ERROR
};

// TODO: unsure if these need to be in a namespace or not
template<class Archive>
void serialize(Archive & ar, ResponseType_t & response, const unsigned int version) {
ar & static_cast<int>(response); // have to type cast enum class
}

// OBC requesting camera for something
struct CameraRequest_t
{
// device id that requests (for debugging)
int pid;

// type of request, we should figure out edge cases
RequestType_t requestType;

template<class Archive>
void serialize(Archive & ar, const unsigned int version) {
ar & pid;
ar & requestType;
}
};

// Response back from camera to OBC
struct CameraResponse_t
{
int pid;
ResponseType_t responseType;
ImageData_t imageData;

template<class Archive>
void serialize(Archive & ar, const unsigned int version) {
ar & pid;
ar & responseType;
ar & imageData;
}
};

#endif
27 changes: 27 additions & 0 deletions include/network/rpi_connection.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#ifndef INCLUDE_NETWORK_RPI_CONNECTION_HPP_
#define INCLUDE_NETWORK_RPI_CONNECTION_HPP_

#include <iostream>

const uint32_t IMG_WIDTH = 2028;
const uint32_t IMG_HEIGHT = 1520;
const uint32_t BUFFER_SIZE = IMG_WIDTH * IMG_HEIGHT * 3 / 2;

// const std::string SERVER_IP = "192.168.68.1";
// const int SERVER_PORT = 25565;

// local testing only
const std::string SERVER_IP = "0.0.0.0";
const int SERVER_PORT = 5000;

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;
};

#endif
28 changes: 28 additions & 0 deletions include/network/serialize.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#ifndef INCLUDE_NETWORK_SERIALIZE_HPP_
#define INCLUDE_NETWORK_SERIALIZE_HPP_

#include <boost/asio.hpp>

/*
Includes some reference on how to serialize and deserialize structs
*/

namespace serialh {
// TODO: make this so that it returns any struct
template <typename T>
void serialize(T* response, boost::asio::streambuf* buf) {
std::ostream os(buf);
boost::archive::binary_oarchive oa(os);
oa << *response;
}

// TODO: make this so that it returns any struct
template <typename T>
void deserialize(T* response, boost::asio::streambuf* buf) {
std::istream is(buf);
boost::archive::binary_iarchive ia(is);
ia >> *response;
}
}

#endif
4 changes: 0 additions & 4 deletions include/network/server.hpp

This file was deleted.

50 changes: 50 additions & 0 deletions include/network/tcp_client.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#ifndef INCLUDE_NETWORK_CLIENT_HPP_
#define INCLUDE_NETWORK_CLIENT_HPP_

#include <iostream>
#include <boost/asio.hpp>
#include <opencv2/opencv.hpp>
#include "rpi_connection.hpp"

namespace asio = boost::asio;

class Client {
private:
asio::ip::tcp::socket socket_;
std::string ip;
int port;

public:

// TODO: should probably make the io_context a unique_ptr
Client(asio::io_context* io_context_, std::string ip, int port);

// TODO: do we need a destructor? probably to free the socket right?
// ~Client();

/**
* Connects to the specified ip and port
*/
bool connect();

/**
*
*/
// TODO: so send is supposed to send a char but im unsure what the type should be uchar, uint8_t, etc.
bool send(std::uint8_t request);

/**
* Reads in the header and fills a Header struct
*/
// std::optional<Header>
Header recvHeader();

/**
* Reads the actual data specified by the header
*/
// std::optional<std::vector<std::uint8_t>>
std::vector<std::uint8_t> recvBody(const int bufSize);

};

#endif
37 changes: 37 additions & 0 deletions include/network/tcp_server.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#ifndef INCLUDE_NETWORK_TCP_SERVER_HPP_
#define INCLUDE_NETWORK_TCP_SERVER_HPP_

#include <iostream>
#include <boost/asio.hpp>
#include <opencv2/opencv.hpp>

namespace asio = boost::asio;

class Server {
private:
std::string ip;
int port;
asio::ip::tcp::socket socket_;
asio::ip::tcp::acceptor acceptor_;

void takePicture();

cv::Mat createBGR();

cv::Mat createYUV();

public:
Server(asio::io_context* io_context_, std::string ip, int port);

void start();

void send();

void recv();

void handleRequest(char request);

void shutdown();
};

#endif
31 changes: 31 additions & 0 deletions include/network/udp_client.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#ifndef INCLUDE_NETWORK_UDP_CLIENT_HPP_
#define INCLUDE_NETWORK_UDP_CLIENT_HPP_

#include <iostream>
#include <boost/asio.hpp>
#include <opencv2/opencv.hpp>
#include <loguru.hpp>
#include "rpi_connection.hpp"

namespace asio = boost::asio;

class UDPClient {
private:
asio::ip::udp::socket socket_;
std::string ip;
int port;

public:
UDPClient(asio::io_context* io_context_, std::string ip, int port);

// there isnt really a notion of connect with connectionless udp sockets
bool connect();

bool send(std::uint8_t request);

Header recvHeader();

std::vector<std::uint8_t> recvBody(const int mem_size, const int total_chunks);
};

#endif
Loading
Loading