-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Create WebSocket for Webcam Interface (#9) * Added websocket prototype using websocket++ * Update CXXFLAGS to be more specific * Update BUILD_GUIDE dependencies Added 'WebSocket++' and 'boost' to the list of additional dependencies in BUILD_GUIDE.md. * Remove header files * Add variables for Websocketpp and Boost libraries * Update path for Websocketpp and Boost * Update build guide * Prevent server from crashing when the client abruptly closes the connection * Update docs * Remove std:: * Downgrade to c++17 * Add Build and Test GitHub Action * Rename workflow * separated the webcam module into web and webcam modules (#12) * Webcam Plant Detection (#13) * changes for webCam * Added hpp file, minor style fixes, deleted output files --------- Co-authored-by: emilysxng Co-authored-by: CihanBosnali <[email protected]> --------- Co-authored-by: Asad Dhorajiwala <[email protected]> Co-authored-by: Alfredo-del-Rayo <[email protected]> Co-authored-by: droy4405 <[email protected]>
- Loading branch information
1 parent
3dcdb2e
commit 1ff732b
Showing
12 changed files
with
311 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
name: Build and Test | ||
|
||
on: | ||
pull_request: | ||
branches: [ main ] | ||
|
||
jobs: | ||
build: | ||
|
||
runs-on: ubuntu-22.04 | ||
|
||
steps: | ||
- uses: actions/checkout@v3 | ||
|
||
- name: Update Package Index | ||
run: sudo apt-get update | ||
|
||
- name: Install Boost | ||
run: sudo apt-get install -y libboost-all-dev | ||
|
||
- name: Install OpenCV | ||
run: sudo apt-get install -y libopencv-dev | ||
|
||
- name: Install WebSocket++ | ||
run: | | ||
git clone --branch 0.8.2 https:/zaphoyd/websocketpp.git | ||
sudo cp -r ./websocketpp/websocketpp ./include | ||
- name: Build project | ||
run: make | ||
|
||
test: | ||
needs: build | ||
|
||
runs-on: ubuntu-22.04 | ||
steps: | ||
- uses: actions/checkout@v3 | ||
- name: Run tests | ||
run: make test_ALL |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
#ifndef INTELCAM_H | ||
#define INTELCAM_H | ||
|
||
#include <librealsense2/rs.hpp> | ||
#include <iostream> | ||
#include <vector> | ||
#include <cmath> | ||
|
||
const float TIME_INTERVAL = 0.01; // Time interval in seconds | ||
const double RAD_TO_DEG = 180.0 / M_PI; | ||
|
||
|
||
using namespace std | ||
|
||
class realIntelCam | ||
{ | ||
public: | ||
|
||
RealIntelCam(); | ||
|
||
void update_camera_position(); | ||
|
||
vector<float> get_location(); | ||
|
||
vector<float> get_angle(); | ||
|
||
private: | ||
//Essential to initiate connection | ||
rs2::pipeline pipeline; | ||
rs2::config configure; | ||
rs2::pipeline_profile profile; | ||
// the acceleration in 3D previous: 0->x, 1->y, 2->z current 3->x, 4->y, 5->z | ||
float acceleration[]{}; | ||
// average velocity aka speed | ||
float velocity[]{}; | ||
// calculated location | ||
float camera_location[]; | ||
//calculated angle | ||
float camera_angle[]; | ||
} | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
#ifndef WEB_INTERFACE_HPP | ||
#define WEB_INTERFACE_HPP | ||
|
||
int web(Mat *frame); | ||
|
||
#endif // WEBCAM_INTERFACE_HPP |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
#ifndef WEBCAMPLANTDETECTION_HPP | ||
#define WEBCAMPLANTDETECTION_HPP | ||
|
||
#include <opencv2/opencv.hpp> | ||
using namespace cv; | ||
|
||
Mat isGreen(const Mat& image); | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
build_/mnt/c/Users/adelr/Documents/Agrobot/new-intel-realsense-imu-interface-Alfredo/.git/Navi/src/sample_submodule build_/mnt/c/Users/adelr/Documents/Agrobot/new-intel-realsense-imu-interface-Alfredo/.git/Navi/src/grass_killer build_/mnt/c/Users/adelr/Documents/Agrobot/new-intel-realsense-imu-interface-Alfredo/.git/Navi/src/imu_interface | ||
mkdir -p /mnt/c/Users/adelr/Documents/Agrobot/new-intel-realsense-imu-interface-Alfredo/.git/Navi/build/objs | ||
mkdir -p /mnt/c/Users/adelr/Documents/Agrobot/new-intel-realsense-imu-interface-Alfredo/.git/Navi/build | ||
g++ -I /mnt/c/Users/adelr/Documents/Agrobot/new-intel-realsense-imu-interface-Alfredo/.git/Navi/include -c /mnt/c/Users/adelr/Documents/Agrobot/new-intel-realsense-imu-interface-Alfredo/.git/Navi/src/sample_submodule/submodule.cpp -o /mnt/c/Users/adelr/Documents/Agrobot/new-intel-realsense-imu-interface-Alfredo/.git/Navi/build/objs/submodule.o | ||
g++ -I /mnt/c/Users/adelr/Documents/Agrobot/new-intel-realsense-imu-interface-Alfredo/.git/Navi/include -c /mnt/c/Users/adelr/Documents/Agrobot/new-intel-realsense-imu-interface-Alfredo/.git/Navi/src/sample_submodule/arg.cpp -o /mnt/c/Users/adelr/Documents/Agrobot/new-intel-realsense-imu-interface-Alfredo/.git/Navi/build/objs/arg.o | ||
g++ -I /mnt/c/Users/adelr/Documents/Agrobot/new-intel-realsense-imu-interface-Alfredo/.git/Navi/include -c /mnt/c/Users/adelr/Documents/Agrobot/new-intel-realsense-imu-interface-Alfredo/.git/Navi/src/grass_killer/grass_killer.cpp -o /mnt/c/Users/adelr/Documents/Agrobot/new-intel-realsense-imu-interface-Alfredo/.git/Navi/build/objs/grass_killer.o | ||
g++ -I /mnt/c/Users/adelr/Documents/Agrobot/new-intel-realsense-imu-interface-Alfredo/.git/Navi/include -c /mnt/c/Users/adelr/Documents/Agrobot/new-intel-realsense-imu-interface-Alfredo/.git/Navi/src/imu_interface/measure.cpp -o /mnt/c/Users/adelr/Documents/Agrobot/new-intel-realsense-imu-interface-Alfredo/.git/Navi/build/objs/measure.o | ||
[[[[ BUILDING NAVI ]]]] | ||
g++ /mnt/c/Users/adelr/Documents/Agrobot/new-intel-realsense-imu-interface-Alfredo/.git/Navi/build/objs/main.o /mnt/c/Users/adelr/Documents/Agrobot/new-intel-realsense-imu-interface-Alfredo/.git/Navi/build/objs/submodule.o /mnt/c/Users/adelr/Documents/Agrobot/new-intel-realsense-imu-interface-Alfredo/.git/Navi/build/objs/arg.o /mnt/c/Users/adelr/Documents/Agrobot/new-intel-realsense-imu-interface-Alfredo/.git/Navi/build/objs/grass_killer.o /mnt/c/Users/adelr/Documents/Agrobot/new-intel-realsense-imu-interface-Alfredo/.git/Navi/build/objs/measure.o -o /mnt/c/Users/adelr/Documents/Agrobot/new-intel-realsense-imu-interface-Alfredo/.git/Navi/navi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
GENERATED_OBJS := webcamPlantDetection.o | ||
|
||
include submodule.general.mk | ||
|
||
build_$(DIR): | ||
$(call build,webcamPlantDetection.cpp) | ||
clean_$(DIR): | ||
test_$(DIR): | ||
@echo testing the module $(DIR)! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
#include <opencv2/opencv.hpp> | ||
#include <iostream> | ||
using namespace std; | ||
using namespace cv; | ||
|
||
Mat isGreen(const Mat& image) { | ||
Mat hsvImage; | ||
Mat mask; | ||
Scalar lower(35, 60, 60); | ||
Scalar upper(80, 255, 255); | ||
cvtColor(image, hsvImage, COLOR_RGB2HSV); | ||
inRange(hsvImage, lower, upper, mask); | ||
return mask; | ||
} | ||
|
||
int test_isGreen() { | ||
Mat myImage; | ||
VideoCapture cap(0); | ||
if (!cap.isOpened()) | ||
return 5; // IO Error Code on Linux, Access Denied Error Code on Windows | ||
|
||
while (true) { | ||
cap >> myImage; | ||
if (myImage.empty()) | ||
break; | ||
Mat greenMask = isGreen(myImage); | ||
imshow("Video Player", greenMask); | ||
char c = (char)waitKey(25); | ||
if (c == 27) | ||
break; | ||
} | ||
cap.release(); | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
GENERATED_OBJS := web_interface.o | ||
|
||
include submodule.general.mk | ||
|
||
build_$(DIR): | ||
$(call build,web_interface.cpp) | ||
clean_$(DIR): | ||
test_$(DIR): | ||
@echo testing the module $(DIR)! | ||
test_webcam_interface: test_$(DIR) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
#include <websocketpp/config/asio_no_tls.hpp> | ||
#include <websocketpp/server.hpp> | ||
#include <thread> | ||
|
||
using namespace std; | ||
using namespace cv; | ||
|
||
// Alias for websocketpp server | ||
typedef websocketpp::server<websocketpp::config::asio> server; | ||
|
||
/*! | ||
* Handles the connection to the WebSocket server. | ||
* Captures frames from the webcam, encodes them, | ||
* and sends them via the WebSocket connection. | ||
* | ||
* \param hdl The connection handle. | ||
* \param s The WebSocket server. | ||
* \param cap The OpenCV VideoCapture object. | ||
*/ | ||
void handle_connection(websocketpp::connection_hdl hdl, server& s, Mat *frame) { | ||
while (true) { | ||
try { | ||
if (!frame->empty()) { | ||
// Convert OpenCV frame to byte vector | ||
vector<uchar> buffer; | ||
imencode(".jpg", *frame, buffer); | ||
s.send(hdl, buffer.data(), buffer.size(), websocketpp::frame::opcode::binary); | ||
} | ||
else { | ||
cerr << "Couldn't capture frame from webcam." << endl; | ||
break; | ||
} | ||
} catch (websocketpp::exception const & e) { | ||
cout << "Caught websocket exception: " << e.what() << endl; | ||
} | ||
} | ||
} | ||
|
||
/*! | ||
* Initializes and runs the WebSocket server, capturing frames | ||
* from the webcam and sending them via open WebSocket connections. | ||
* | ||
* Clears all access log channels, initializes the OpenCV webcam, | ||
* defines the WebSocket server connection handler, listens on port 6969, | ||
* and finally starts the accept loop and the ASIO io_service event loop. | ||
* | ||
* \return 0 if the server ran successfully, otherwise -1. | ||
*/ | ||
int web(Mat *frame) { | ||
// Create a WebSocket server | ||
server s; | ||
// Clear all access log channels to prevent frames being logged | ||
// If frames are logged, then it makes the WebSocket server very slow | ||
s.clear_access_channels(websocketpp::log::alevel::all); | ||
|
||
s.set_open_handler([&s,frame](websocketpp::connection_hdl hdl) { | ||
thread video_thread(handle_connection, hdl, ref(s), ref(frame)); | ||
video_thread.detach(); | ||
}); | ||
|
||
// Listen on port 6969 | ||
s.init_asio(); | ||
s.listen(6969); | ||
s.start_accept(); | ||
s.run(); | ||
|
||
return 0; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,35 +1,85 @@ | ||
#include<opencv2/opencv.hpp> | ||
#include<iostream> | ||
#include <websocketpp/config/asio_no_tls.hpp> | ||
#include <websocketpp/server.hpp> | ||
#include <opencv2/opencv.hpp> | ||
#include <thread> | ||
|
||
using namespace std; | ||
using namespace cv; | ||
|
||
// Alias for websocketpp server | ||
typedef websocketpp::server<websocketpp::config::asio> server; | ||
|
||
/*! | ||
* @brief Opens and displays the webcam video feed until termination. | ||
* @return Returns 0 upon successful completion, else returns -1. | ||
* Handles the connection to the WebSocket server. | ||
* Captures frames from the webcam, encodes them, | ||
* and sends them via the WebSocket connection. | ||
* | ||
* \param hdl The connection handle. | ||
* \param s The WebSocket server. | ||
* \param cap The OpenCV VideoCapture object. | ||
*/ | ||
void handle_connection(websocketpp::connection_hdl hdl, server& s, VideoCapture& cap) { | ||
try { | ||
while (true) { | ||
// Read frame from webcam | ||
Mat frame; | ||
cap >> frame; | ||
|
||
// Check if frame is empty | ||
if (!frame.empty()) { | ||
// Convert OpenCV frame to byte vector | ||
vector<uchar> buffer; | ||
imencode(".jpg", frame, buffer); | ||
|
||
// Send the frame as a binary message via WebSocket | ||
s.send(hdl, buffer.data(), buffer.size(), websocketpp::frame::opcode::binary); | ||
} | ||
else { | ||
cerr << "Couldn't capture frame from webcam." << endl; | ||
break; | ||
} | ||
} | ||
} catch (websocketpp::exception const & e) { | ||
cout << "Caught websocket exception: " << e.what() << endl; | ||
} | ||
} | ||
|
||
/*! | ||
* Initializes and runs the WebSocket server, capturing frames | ||
* from the webcam and sending them via open WebSocket connections. | ||
* | ||
* Clears all access log channels, initializes the OpenCV webcam, | ||
* defines the WebSocket server connection handler, listens on port 6969, | ||
* and finally starts the accept loop and the ASIO io_service event loop. | ||
* | ||
* \return 0 if the server ran successfully, otherwise -1. | ||
*/ | ||
int webcam() { | ||
Mat myImage; | ||
namedWindow("Webcam Video Feed"); | ||
VideoCapture cap(0); | ||
|
||
if (!cap.isOpened()) { | ||
cout << "No webcam feed detected" << endl; | ||
system("pause"); | ||
return -1; | ||
} | ||
|
||
while (true) { | ||
cap >> myImage; | ||
if (myImage.empty()) { | ||
break; | ||
} | ||
|
||
imshow("Webcam Video Feed", myImage); | ||
char c = (char)waitKey(25); | ||
if (c == 27) { | ||
break; | ||
} | ||
} | ||
cap.release(); | ||
return 0; | ||
// Create a WebSocket server | ||
server s; | ||
|
||
// Clear all access log channels to prevent frames being logged | ||
// If frames are logged, then it makes the WebSocket server very slow | ||
s.clear_access_channels(websocketpp::log::alevel::all); | ||
|
||
// Initialize OpenCV webcam | ||
VideoCapture cap(0); | ||
if (!cap.isOpened()) { | ||
cerr << "Couldn't open the webcam." << endl; | ||
return -1; | ||
} | ||
|
||
// Define WebSocket server connection handler | ||
s.set_open_handler([&s, &cap](websocketpp::connection_hdl hdl) { | ||
thread video_thread(handle_connection, hdl, ref(s), ref(cap)); | ||
video_thread.detach(); | ||
}); | ||
|
||
// Listen on port 6969 | ||
s.init_asio(); | ||
s.listen(6969); | ||
s.start_accept(); | ||
s.run(); | ||
|
||
return 0; | ||
} |