mirror of
https://gitlab.fdmci.hva.nl/technische-informatica-sm3/ti-projectten/rooziinuubii79.git
synced 2025-08-05 12:54:57 +00:00
Compare commits
52 Commits
82c4381143
...
OpenCV
Author | SHA1 | Date | |
---|---|---|---|
c9d3b0f795 | |||
85af15d7a3 | |||
a1b50a3780 | |||
b86528595e | |||
eef4f9c79c | |||
3c23d37be1 | |||
c2886d32c9 | |||
8158c85d6e | |||
e682969ec8 | |||
0dfc3b5c13 | |||
7f786d5197 | |||
60ba177dc2 | |||
e9f998b3e7 | |||
7eeaba482e | |||
e8db00120f | |||
c65f310e81 | |||
ec3e83ef7f | |||
480d36393a | |||
fea0f19857 | |||
e1135dac0f | |||
2f4e5ae096 | |||
|
606506e40c | ||
|
6efd95fb32 | ||
|
5eff7fccba | ||
|
a03894e52e | ||
9e07a243ea | |||
b93a5f2dca | |||
911b870786 | |||
dd2a1b56c4 | |||
dd39bd3021 | |||
|
1563528b67 | ||
|
2e5af52ba8 | ||
|
eb04d35d40 | ||
|
80fcb1ccc3 | ||
|
62cdf98098 | ||
|
db6fa156c9 | ||
|
048790ec8b | ||
8aa54805ac | |||
|
aca6644c02 | ||
|
492f506aa2 | ||
d26d277c3c | |||
c76ba93e82 | |||
508d2ed4e2 | |||
3e202acc8d | |||
0bfba0bffe | |||
|
8a5b349040 | ||
|
a41ea1b70c | ||
eb804c888c | |||
a028a6f88f | |||
47b29a1c55 | |||
528de4f3f4 | |||
|
c16ba3cf9d |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -13,7 +13,7 @@ src/Socket/a.out
|
|||||||
src/C++/Driver/cmake_install.cmake
|
src/C++/Driver/cmake_install.cmake
|
||||||
src/C++/Socket/a.out
|
src/C++/Socket/a.out
|
||||||
src/C++/Driver/Makefile
|
src/C++/Driver/Makefile
|
||||||
src/C++/Driver/vgcore*
|
vgcore*
|
||||||
src/C++/Driver/cmake_install.cmake
|
src/C++/Driver/cmake_install.cmake
|
||||||
src/C++/Driver/Makefile
|
src/C++/Driver/Makefile
|
||||||
src/C++/Driver/log
|
src/C++/Driver/log
|
||||||
@@ -31,3 +31,4 @@ CMakeFiles/
|
|||||||
Makefile
|
Makefile
|
||||||
CMakeCache.txt
|
CMakeCache.txt
|
||||||
cmake_install.cmake
|
cmake_install.cmake
|
||||||
|
src/C++/OpenCV/main
|
||||||
|
20
docs/code/OpenCV.md
Normal file
20
docs/code/OpenCV.md
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
# OpenCV
|
||||||
|
## Requirements
|
||||||
|
For the camera we want it to detect what is happening on the video feed and identify it so it can identify dangers.
|
||||||
|
|
||||||
|
|
||||||
|
## Issues
|
||||||
|
|
||||||
|
* OpenCL not grabbing gpu
|
||||||
|
* Solution: https://github.com/Smorodov/Multitarget-tracker/issues/93
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
### Dependencies
|
||||||
|
* glew
|
||||||
|
* opencv
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Sources
|
||||||
|
* https://github.com/UnaNancyOwen/OpenCVDNNSample/tree/master
|
10
docs/code/code-requirements.md
Normal file
10
docs/code/code-requirements.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# Requirements
|
||||||
|
|
||||||
|
1. Het compileerd op x86 en ARM architechturen
|
||||||
|
2. Geen dubbele code
|
||||||
|
3. commentaar bij lastige code
|
||||||
|
4. Doxygen comments bij elke functie, behalve als het duidelijk is in de functienaam
|
||||||
|
5. Hou je code leesbaar
|
||||||
|
6. Geen dode code
|
||||||
|
7. Gebruik TODO comments (TODO TREE)
|
||||||
|
8.
|
@@ -1,13 +1,20 @@
|
|||||||
# Daily stand ups
|
# Daily stand ups
|
||||||
|
|
||||||
??? note "Daily Stand-ups Sprint 4"
|
??? note "Daily Stand-ups Sprint 4"
|
||||||
| Day | Submitted by | What did you do yesterday | What will you do today | Any blockers? |
|
| Day | Submitted by | What did you do yesterday | What will you do today | Any blockers? |
|
||||||
| ---------- | ------------ | ----------------------------- | -------------------------------------------------- | ----------------------- |
|
| ---------- | ------------ | ----------------------------- | -------------------------------------------------- | ------------------------------------ |
|
||||||
| 18/11/2024 | Ishak | --- | Engels, Repo fixen, beginnen met nieuwe user story | --- |
|
| 18/11/2024 | Ishak | --- | Engels, Repo fixen, beginnen met nieuwe user story | --- |
|
||||||
| 18/11/2024 | Sam | --- | Engels, Feedback verwerken medium stake | None |
|
| 18/11/2024 | Sam | --- | Engels, Feedback verwerken medium stake | None |
|
||||||
| 18/11/2024 | Yannick | --- | Engels, Documentatie, Code samenvoegen | None |
|
| 18/11/2024 | Yannick | --- | Engels, Documentatie, Code samenvoegen | None |
|
||||||
| 18/11/2024 | Mees | --- | Engels, Onderzoek | None |
|
| 18/11/2024 | Mees | --- | Engels, Onderzoek | None |
|
||||||
| 19/11/2024 | Ishak | Engels, Repo fixen | workshop | --- |
|
| 19/11/2024 | Ishak | Engels, Repo fixen | workshop | --- |
|
||||||
| 19/11/2024 | Sam | Engels, Feedback verwerken | workshop | None |
|
| 19/11/2024 | Sam | Engels, Feedback verwerken | workshop | None |
|
||||||
| 19/11/2024 | Yannick | code samenvoegen,schema maken | workshop, documentatie | None |
|
| 19/11/2024 | Yannick | code samenvoegen,schema maken | workshop, documentatie | None |
|
||||||
| 19/11/2024 | Mees | niks | workshop, fixen include path | include path werkt niet |
|
| 19/11/2024 | Mees | niks | workshop, fixen include path | include path werkt niet |
|
||||||
|
| 26/11/2024 | Ishak | Workshop | database, engels video opnemen | phpmyadmin werkt niet(weet probleem) |
|
||||||
|
| 26/11/2024 | Sam | opencv | opencv | --- |
|
||||||
|
| 26/11/2024 | Yannick | ziek | ziek | --- |
|
||||||
|
| 26/11/2024 | Mees | Engels video | stepper motor | vscode werkt niet |
|
||||||
|
| 02/12/2024 | Ishak | database | database | --- |
|
||||||
|
| 02/12/2024 | Sam | opencv | camera beeld op website | --- |
|
||||||
|
| 02/12/2024 | Yannick | ziek, documentatie | behuizing voor esp | --- |
|
12
docs/scrum/review_feedback.md
Normal file
12
docs/scrum/review_feedback.md
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
# sprint review 4 feedback
|
||||||
|
|
||||||
|
- Definition of done SMART maken
|
||||||
|
- Uitgebreider beschrijven wat er voor de definition of done nodig is
|
||||||
|
- Testen van de software niet meer dan een halve A4
|
||||||
|
- Acceptatie criteria beter uitschrijven( vragen aan ed)
|
||||||
|
- Meer software ontwikkelen
|
||||||
|
- kijken of we met een punten systeem kunnen werken in user stories. zo kan je zien hoe groot een user story is.
|
||||||
|
- read.me file aanpassen
|
||||||
|
- meer aan documentatie doen.
|
||||||
|
- technisch iets te uitdagend
|
||||||
|
- planning beter maken
|
@@ -6,7 +6,10 @@ set(CMAKE_CXX_STANDARD 23)
|
|||||||
find_library(PAHO_MQTTPP_LIBRARY paho-mqttpp3 PATHS /usr/local/lib)
|
find_library(PAHO_MQTTPP_LIBRARY paho-mqttpp3 PATHS /usr/local/lib)
|
||||||
find_library(PAHO_MQTT_LIBRARY paho-mqtt3a PATHS /usr/local/lib)
|
find_library(PAHO_MQTT_LIBRARY paho-mqtt3a PATHS /usr/local/lib)
|
||||||
|
|
||||||
include_directories(/usr/local/include)
|
# Find OpenCV package
|
||||||
|
find_package(OpenCV REQUIRED)
|
||||||
|
find_package(OpenEXR REQUIRED)
|
||||||
|
include_directories(${OpenCV_INCLUDE_DIRS})
|
||||||
|
|
||||||
set(SOURCE_FILES
|
set(SOURCE_FILES
|
||||||
src/KobukiDriver/KobukiParser.cpp
|
src/KobukiDriver/KobukiParser.cpp
|
||||||
@@ -20,4 +23,4 @@ set(SOURCE_FILES
|
|||||||
add_executable(kobuki_control ${SOURCE_FILES})
|
add_executable(kobuki_control ${SOURCE_FILES})
|
||||||
|
|
||||||
# Link the static libraries
|
# Link the static libraries
|
||||||
target_link_libraries(kobuki_control ${PAHO_MQTTPP_LIBRARY} ${PAHO_MQTT_LIBRARY} pthread)
|
target_link_libraries(kobuki_control ${PAHO_MQTTPP_LIBRARY} ${PAHO_MQTT_LIBRARY} ${OpenCV_LIBS} pthread OpenEXR::OpenEXR)
|
||||||
|
@@ -509,32 +509,8 @@ void CKobuki::doRotation(long double th) {
|
|||||||
usleep(25 * 1000);
|
usleep(25 * 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
// combines navigation to a coordinate and rotation by an angle, performs
|
/// @brief Makes the robot move forward for 3 seconds
|
||||||
// movement to the selected coordinate in the robot's coordinate system
|
/// @param speedvalue How fast it will drive forward from 0 - 1024
|
||||||
void CKobuki::goToXy(long double xx, long double yy) {
|
|
||||||
long double th;
|
|
||||||
|
|
||||||
yy = yy * -1;
|
|
||||||
|
|
||||||
th = atan2(yy, xx);
|
|
||||||
doRotation(th);
|
|
||||||
|
|
||||||
long double s = sqrt(pow(xx, 2) + pow(yy, 2));
|
|
||||||
|
|
||||||
// resetnem suradnicovu sustavu robota
|
|
||||||
x = 0;
|
|
||||||
y = 0;
|
|
||||||
iterationCount = 0;
|
|
||||||
theta = 0;
|
|
||||||
|
|
||||||
// std::cout << "mam prejst: " << s << "[m]" << std::endl;
|
|
||||||
|
|
||||||
goStraight(s);
|
|
||||||
|
|
||||||
usleep(25 * 1000);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CKobuki::forward(int speedvalue) {
|
void CKobuki::forward(int speedvalue) {
|
||||||
// Use the goStraight logic to determine the speed and distance
|
// Use the goStraight logic to determine the speed and distance
|
||||||
|
|
||||||
@@ -572,10 +548,10 @@ void CKobuki::Rotate(int degrees) {
|
|||||||
float radians = degrees * PI / 180.0;
|
float radians = degrees * PI / 180.0;
|
||||||
|
|
||||||
// Calculate the rotation speed in radians per second
|
// Calculate the rotation speed in radians per second
|
||||||
double radpersec = 1;
|
double RADS_PER_SEC = 1;
|
||||||
|
|
||||||
// calculator rotation time and give absolute value
|
// calculator rotation time and give absolute value
|
||||||
float rotation_time = std::abs(radians / radpersec);
|
float rotation_time = std::abs(radians / RADS_PER_SEC);
|
||||||
|
|
||||||
// Use original function to set the rotation speed in mm/s
|
// Use original function to set the rotation speed in mm/s
|
||||||
setRotationSpeed(radians);
|
setRotationSpeed(radians);
|
||||||
@@ -588,6 +564,10 @@ void CKobuki::Rotate(int degrees) {
|
|||||||
setRotationSpeed(0);
|
setRotationSpeed(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// @brief Robot safety function to be ran in another thread. Makes sure the robot does not throw inteself from the table. Only use this when the speed is lower than 350
|
||||||
|
/// @param pointerToMessage Set this pointer to the control message and then it attempts to reset it when it bumps into something so it doesnt keep trying to do the past commant
|
||||||
|
// TODO: make this return bool so it can be used in the control part
|
||||||
void CKobuki::robotSafety(std::string *pointerToMessage) {
|
void CKobuki::robotSafety(std::string *pointerToMessage) {
|
||||||
while (true) {
|
while (true) {
|
||||||
|
|
||||||
@@ -602,6 +582,7 @@ void CKobuki::robotSafety(std::string *pointerToMessage) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @brief Robot safety function to be ran in another thread. Makes sure the robot does not throw inteself from the table. Only use this when the speed is lower than 350
|
||||||
void CKobuki::robotSafety() {
|
void CKobuki::robotSafety() {
|
||||||
while (true) {
|
while (true) {
|
||||||
|
|
||||||
@@ -614,6 +595,7 @@ void CKobuki::robotSafety() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @brief When called the robot gets a control message to stop whatever its doing
|
||||||
void CKobuki::sendNullMessage() {
|
void CKobuki::sendNullMessage() {
|
||||||
|
|
||||||
unsigned char message[11] = {
|
unsigned char message[11] = {
|
||||||
|
@@ -31,7 +31,6 @@
|
|||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include "KobukiParser.h"
|
#include "KobukiParser.h"
|
||||||
#include "graph.h"
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
@@ -1,71 +0,0 @@
|
|||||||
#ifndef GRAPH1010
|
|
||||||
#define GRAPH1010
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
#define GRAPH_ENABLED true
|
|
||||||
|
|
||||||
class plot {
|
|
||||||
public:
|
|
||||||
FILE *gp;
|
|
||||||
bool enabled,persist;
|
|
||||||
plot(bool _persist=false,bool _enabled=GRAPH_ENABLED) {
|
|
||||||
enabled=_enabled;
|
|
||||||
persist=_persist;
|
|
||||||
if (enabled) {
|
|
||||||
if(persist)
|
|
||||||
gp=popen("gnuplot -persist","w");
|
|
||||||
else
|
|
||||||
gp=popen("gnuplot","w");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void plot_data(vector<float> x,const char* style="points",const char* title="Data") {
|
|
||||||
if(!enabled)
|
|
||||||
return;
|
|
||||||
fprintf(gp,"set title '%s' \n",title);
|
|
||||||
fprintf(gp,"plot '-' w %s \n",style);
|
|
||||||
for(int k=0;k<x.size();k++) {
|
|
||||||
fprintf(gp,"%f\n",x[k]);
|
|
||||||
}
|
|
||||||
fprintf(gp,"e\n");
|
|
||||||
fflush(gp);
|
|
||||||
}
|
|
||||||
|
|
||||||
void plot_data(vector<float> x,vector<float> y,const char* style="points",const char* title="Data") {
|
|
||||||
if(!enabled)
|
|
||||||
return;
|
|
||||||
fprintf(gp,"set title '%s' \n",title);
|
|
||||||
fprintf(gp,"plot '-' w %s \n",style);
|
|
||||||
for(int k=0;k<x.size();k++) {
|
|
||||||
fprintf(gp,"%f %f \n",x[k],y[k]);
|
|
||||||
}
|
|
||||||
fprintf(gp,"e\n");
|
|
||||||
fflush(gp);
|
|
||||||
}
|
|
||||||
|
|
||||||
~plot() {
|
|
||||||
if(enabled)
|
|
||||||
pclose(gp);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
int main(int argc,char **argv) {
|
|
||||||
plot p;
|
|
||||||
for(int a=0;a<100;a++) {
|
|
||||||
vector<float> x,y;
|
|
||||||
for(int k=a;k<a+200;k++) {
|
|
||||||
x.push_back(k);
|
|
||||||
y.push_back(k*k);
|
|
||||||
}
|
|
||||||
p.plot_data(x,y);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
#endif
|
|
@@ -2,8 +2,10 @@
|
|||||||
|
|
||||||
MqttClient::MqttClient(const std::string& address, const std::string& clientId, const std::string& username, const std::string& password)
|
MqttClient::MqttClient(const std::string& address, const std::string& clientId, const std::string& username, const std::string& password)
|
||||||
//client_ is the connection
|
//client_ is the connection
|
||||||
|
//here all the @PARAMS are getting set for the connection
|
||||||
: client_(address, clientId), username_(username), password_(password), callback_(*this) {
|
: client_(address, clientId), username_(username), password_(password), callback_(*this) {
|
||||||
client_.set_callback(callback_);
|
client_.set_callback(callback_);
|
||||||
|
|
||||||
options.set_clean_session(true);
|
options.set_clean_session(true);
|
||||||
options.set_mqtt_version(MQTTVERSION_3_1_1); // For MQTT 3.1.1
|
options.set_mqtt_version(MQTTVERSION_3_1_1); // For MQTT 3.1.1
|
||||||
if (!username_.empty() && !password_.empty()) {
|
if (!username_.empty() && !password_.empty()) {
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
#include "MqttClient.h"
|
#include "MqttClient.h"
|
||||||
|
//example file for testing
|
||||||
int main(){
|
int main(){
|
||||||
MqttClient client("mqtt://localhost:1883", "raspberry_pi_client", "ishak", "kobuki");
|
MqttClient client("mqtt://localhost:1883", "raspberry_pi_client", "ishak", "kobuki");
|
||||||
client.connect();
|
client.connect();
|
||||||
|
@@ -1,15 +1,19 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include "KobukiDriver/graph.h"
|
|
||||||
#include "MQTT/MqttClient.h"
|
#include "MQTT/MqttClient.h"
|
||||||
#include "KobukiDriver/CKobuki.h"
|
#include "KobukiDriver/CKobuki.h"
|
||||||
|
#include <opencv4/opencv2/opencv.hpp>
|
||||||
|
#include <opencv4/opencv2/core.hpp>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
using namespace cv;
|
||||||
CKobuki robot;
|
CKobuki robot;
|
||||||
std::string readMQTT();
|
std::string readMQTT();
|
||||||
void parseMQTT(std::string message);
|
void parseMQTT(std::string message);
|
||||||
MqttClient client("mqtt://145.92.224.21:1883", "KobukiRPI", "ishak", "kobuki"); // create a client object
|
void CapnSend();
|
||||||
|
//ip, clientID, username, password
|
||||||
|
MqttClient client("ws://145.92.224.21/ws/", "KobukiRPI", "rpi", "rpiwachtwoordofzo"); // create a client object
|
||||||
std::string message = "stop";
|
std::string message = "stop";
|
||||||
std::string serializeKobukiData(const TKobukiData &data);
|
std::string serializeKobukiData(const TKobukiData &data);
|
||||||
void sendKobukiData(TKobukiData &data);
|
void sendKobukiData(TKobukiData &data);
|
||||||
@@ -18,6 +22,8 @@ void setup()
|
|||||||
{
|
{
|
||||||
unsigned char *null_ptr(0);
|
unsigned char *null_ptr(0);
|
||||||
robot.startCommunication("/dev/ttyUSB0", true, null_ptr);
|
robot.startCommunication("/dev/ttyUSB0", true, null_ptr);
|
||||||
|
//connect mqtt server and sub to commands
|
||||||
|
|
||||||
client.connect();
|
client.connect();
|
||||||
client.subscribe("home/commands");
|
client.subscribe("home/commands");
|
||||||
}
|
}
|
||||||
@@ -25,15 +31,17 @@ void setup()
|
|||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
setup();
|
setup();
|
||||||
|
std::thread image (CapnSend);
|
||||||
std::thread safety([&]() { robot.robotSafety(&message); });
|
std::thread safety([&]() { robot.robotSafety(&message); });
|
||||||
std::thread sendMqtt([&]() { sendKobukiData(robot.parser.data); });
|
std::thread sendMqtt([&]() { sendKobukiData(robot.parser.data); });
|
||||||
|
|
||||||
while(true){
|
while(true){
|
||||||
parseMQTT(readMQTT());
|
parseMQTT(readMQTT());
|
||||||
}
|
}
|
||||||
|
|
||||||
sendMqtt.join();
|
sendMqtt.join();
|
||||||
safety.join();
|
safety.join();
|
||||||
return 0;
|
image.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string readMQTT()
|
std::string readMQTT()
|
||||||
@@ -53,7 +61,7 @@ void parseMQTT(std::string message)
|
|||||||
{
|
{
|
||||||
if (message == "up")
|
if (message == "up")
|
||||||
{
|
{
|
||||||
robot.forward(1024);
|
robot.forward(350);
|
||||||
}
|
}
|
||||||
else if (message == "left")
|
else if (message == "left")
|
||||||
{
|
{
|
||||||
@@ -65,7 +73,7 @@ void parseMQTT(std::string message)
|
|||||||
}
|
}
|
||||||
else if (message == "down")
|
else if (message == "down")
|
||||||
{
|
{
|
||||||
robot.forward(-800);
|
robot.forward(-350);
|
||||||
}
|
}
|
||||||
else if (message == "stop")
|
else if (message == "stop")
|
||||||
{
|
{
|
||||||
@@ -149,6 +157,64 @@ void logToFile()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sendIndividualKobukiData(const TKobukiData &data) {
|
||||||
|
while (true) {
|
||||||
|
client.publishMessage("kobuki/data/timestamp", std::to_string(data.timestamp));
|
||||||
|
client.publishMessage("kobuki/data/BumperCenter", std::to_string(data.BumperCenter));
|
||||||
|
client.publishMessage("kobuki/data/BumperLeft", std::to_string(data.BumperLeft));
|
||||||
|
client.publishMessage("kobuki/data/BumperRight", std::to_string(data.BumperRight));
|
||||||
|
client.publishMessage("kobuki/data/WheelDropLeft", std::to_string(data.WheelDropLeft));
|
||||||
|
client.publishMessage("kobuki/data/WheelDropRight", std::to_string(data.WheelDropRight));
|
||||||
|
client.publishMessage("kobuki/data/CliffCenter", std::to_string(data.CliffCenter));
|
||||||
|
client.publishMessage("kobuki/data/CliffLeft", std::to_string(data.CliffLeft));
|
||||||
|
client.publishMessage("kobuki/data/CliffRight", std::to_string(data.CliffRight));
|
||||||
|
client.publishMessage("kobuki/data/EncoderLeft", std::to_string(data.EncoderLeft));
|
||||||
|
client.publishMessage("kobuki/data/EncoderRight", std::to_string(data.EncoderRight));
|
||||||
|
client.publishMessage("kobuki/data/PWMleft", std::to_string(data.PWMleft));
|
||||||
|
client.publishMessage("kobuki/data/PWMright", std::to_string(data.PWMright));
|
||||||
|
client.publishMessage("kobuki/data/ButtonPress1", std::to_string(data.ButtonPress1));
|
||||||
|
client.publishMessage("kobuki/data/ButtonPress2", std::to_string(data.ButtonPress2));
|
||||||
|
client.publishMessage("kobuki/data/ButtonPress3", std::to_string(data.ButtonPress3));
|
||||||
|
client.publishMessage("kobuki/data/Charger", std::to_string(data.Charger));
|
||||||
|
client.publishMessage("kobuki/data/Battery", std::to_string(data.Battery));
|
||||||
|
client.publishMessage("kobuki/data/overCurrent", std::to_string(data.overCurrent));
|
||||||
|
client.publishMessage("kobuki/data/IRSensorRight", std::to_string(data.IRSensorRight));
|
||||||
|
client.publishMessage("kobuki/data/IRSensorCenter", std::to_string(data.IRSensorCenter));
|
||||||
|
client.publishMessage("kobuki/data/IRSensorLeft", std::to_string(data.IRSensorLeft));
|
||||||
|
client.publishMessage("kobuki/data/GyroAngle", std::to_string(data.GyroAngle));
|
||||||
|
client.publishMessage("kobuki/data/GyroAngleRate", std::to_string(data.GyroAngleRate));
|
||||||
|
client.publishMessage("kobuki/data/CliffSensorRight", std::to_string(data.CliffSensorRight));
|
||||||
|
client.publishMessage("kobuki/data/CliffSensorCenter", std::to_string(data.CliffSensorCenter));
|
||||||
|
client.publishMessage("kobuki/data/CliffSensorLeft", std::to_string(data.CliffSensorLeft));
|
||||||
|
client.publishMessage("kobuki/data/wheelCurrentLeft", std::to_string(data.wheelCurrentLeft));
|
||||||
|
client.publishMessage("kobuki/data/wheelCurrentRight", std::to_string(data.wheelCurrentRight));
|
||||||
|
client.publishMessage("kobuki/data/digitalInput", std::to_string(data.digitalInput));
|
||||||
|
client.publishMessage("kobuki/data/analogInputCh0", std::to_string(data.analogInputCh0));
|
||||||
|
client.publishMessage("kobuki/data/analogInputCh1", std::to_string(data.analogInputCh1));
|
||||||
|
client.publishMessage("kobuki/data/analogInputCh2", std::to_string(data.analogInputCh2));
|
||||||
|
client.publishMessage("kobuki/data/analogInputCh3", std::to_string(data.analogInputCh3));
|
||||||
|
client.publishMessage("kobuki/data/frameId", std::to_string(data.frameId));
|
||||||
|
client.publishMessage("kobuki/data/extraInfo/HardwareVersionPatch", std::to_string(data.extraInfo.HardwareVersionPatch));
|
||||||
|
client.publishMessage("kobuki/data/extraInfo/HardwareVersionMinor", std::to_string(data.extraInfo.HardwareVersionMinor));
|
||||||
|
client.publishMessage("kobuki/data/extraInfo/HardwareVersionMajor", std::to_string(data.extraInfo.HardwareVersionMajor));
|
||||||
|
client.publishMessage("kobuki/data/extraInfo/FirmwareVersionPatch", std::to_string(data.extraInfo.FirmwareVersionPatch));
|
||||||
|
client.publishMessage("kobuki/data/extraInfo/FirmwareVersionMinor", std::to_string(data.extraInfo.FirmwareVersionMinor));
|
||||||
|
client.publishMessage("kobuki/data/extraInfo/FirmwareVersionMajor", std::to_string(data.extraInfo.FirmwareVersionMajor));
|
||||||
|
client.publishMessage("kobuki/data/extraInfo/UDID0", std::to_string(data.extraInfo.UDID0));
|
||||||
|
client.publishMessage("kobuki/data/extraInfo/UDID1", std::to_string(data.extraInfo.UDID1));
|
||||||
|
client.publishMessage("kobuki/data/extraInfo/UDID2", std::to_string(data.extraInfo.UDID2));
|
||||||
|
|
||||||
|
if (!data.gyroData.empty()) {
|
||||||
|
const auto& latestGyro = data.gyroData.back();
|
||||||
|
client.publishMessage("kobuki/data/gyroData/x", std::to_string(latestGyro.x));
|
||||||
|
client.publishMessage("kobuki/data/gyroData/y", std::to_string(latestGyro.y));
|
||||||
|
client.publishMessage("kobuki/data/gyroData/z", std::to_string(latestGyro.z));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::string serializeKobukiData(const TKobukiData &data) {
|
std::string serializeKobukiData(const TKobukiData &data) {
|
||||||
std::string json = "{\"timestamp\":" + std::to_string(data.timestamp) +
|
std::string json = "{\"timestamp\":" + std::to_string(data.timestamp) +
|
||||||
",\"BumperCenter\":" + std::to_string(data.BumperCenter) +
|
",\"BumperCenter\":" + std::to_string(data.BumperCenter) +
|
||||||
@@ -210,6 +276,35 @@ std::string serializeKobukiData(const TKobukiData &data) {
|
|||||||
void sendKobukiData(TKobukiData &data) {
|
void sendKobukiData(TKobukiData &data) {
|
||||||
while (true) {
|
while (true) {
|
||||||
client.publishMessage("kobuki/data", serializeKobukiData(data));
|
client.publishMessage("kobuki/data", serializeKobukiData(data));
|
||||||
|
std::cout << "Sent data" << std::endl;
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CapnSend() {
|
||||||
|
VideoCapture cap(0);
|
||||||
|
if (!cap.isOpened()) {
|
||||||
|
cerr << "Error: Could not open camera" << endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Mat frame;
|
||||||
|
while (true) {
|
||||||
|
cap >> frame; // Capture a new image frame
|
||||||
|
if (frame.empty()) {
|
||||||
|
cerr << "Error: Could not capture image" << endl;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert the image to a byte array
|
||||||
|
vector<uchar> buf;
|
||||||
|
imencode(".jpg", frame, buf);
|
||||||
|
auto* enc_msg = reinterpret_cast<unsigned char*>(buf.data());
|
||||||
|
|
||||||
|
// Publish the image data
|
||||||
|
client.publishMessage("kobuki/cam", string(enc_msg, enc_msg + buf.size()));
|
||||||
|
cout << "Sent image" << endl;
|
||||||
|
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(300)); // Send image every 1000ms
|
||||||
|
}
|
||||||
}
|
}
|
@@ -1,15 +0,0 @@
|
|||||||
cmake_minimum_required(VERSION 3.10)
|
|
||||||
set(CMAKE_CXX_STANDARD 23)
|
|
||||||
|
|
||||||
# Find the Paho MQTT C++ library
|
|
||||||
find_library(PAHO_MQTTPP_LIBRARY paho-mqttpp3 PATHS /usr/local/lib)
|
|
||||||
find_library(PAHO_MQTT_LIBRARY paho-mqtt3a PATHS /usr/local/lib)
|
|
||||||
|
|
||||||
# Include the headers
|
|
||||||
include_directories(/usr/local/include)
|
|
||||||
|
|
||||||
# Add the executable
|
|
||||||
add_executable(my_program main.cpp)
|
|
||||||
|
|
||||||
# Link the libraries
|
|
||||||
target_link_libraries(my_program ${PAHO_MQTTPP_LIBRARY} ${PAHO_MQTT_LIBRARY})
|
|
@@ -1,64 +0,0 @@
|
|||||||
#include <iostream>
|
|
||||||
#include <mqtt/async_client.h>
|
|
||||||
#include <thread> // For std::this_thread::sleep_for
|
|
||||||
#include <chrono> // For std::chrono::seconds
|
|
||||||
|
|
||||||
// Define the address of the MQTT broker, the client ID, and the topic to subscribe to.
|
|
||||||
const std::string ADDRESS("mqtt://localhost:1883"); // Broker address (Raspberry Pi)
|
|
||||||
const std::string CLIENT_ID("raspberry_pi_client");
|
|
||||||
const std::string TOPIC("home/commands");
|
|
||||||
|
|
||||||
// Define a callback class that handles incoming messages and connection events.
|
|
||||||
class callback : public virtual mqtt::callback {
|
|
||||||
// Called when a message arrives on a subscribed topic.
|
|
||||||
void message_arrived(mqtt::const_message_ptr msg) override {
|
|
||||||
std::cout << "Received message: '" << msg->get_topic()<< "' : " << msg->to_string() << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Called when the connection to the broker is lost.
|
|
||||||
void connection_lost(const std::string& cause) override {
|
|
||||||
std::cerr << "Connection lost. Reason: " << cause << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Called when a message delivery is complete.
|
|
||||||
void delivery_complete(mqtt::delivery_token_ptr token) override {
|
|
||||||
std::cout << "Message delivered!" << std::endl;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
// Create an MQTT async client and set up the callback class.
|
|
||||||
mqtt::async_client client(ADDRESS, CLIENT_ID);
|
|
||||||
callback cb;
|
|
||||||
client.set_callback(cb);
|
|
||||||
|
|
||||||
// Set up the connection options (such as username and password).
|
|
||||||
mqtt::connect_options connOpts;
|
|
||||||
connOpts.set_clean_session(true);
|
|
||||||
connOpts.set_user_name("ishak");
|
|
||||||
connOpts.set_password("kobuki");
|
|
||||||
connOpts.set_mqtt_version(MQTTVERSION_3_1_1);
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Try to connect to the broker and wait until successful.
|
|
||||||
std::cout << "Connecting to broker..." << std::endl;
|
|
||||||
client.connect(connOpts)->wait(); // Connect with the provided options
|
|
||||||
std::cout << "Connected!" << std::endl;
|
|
||||||
|
|
||||||
// Subscribe to the specified topic and wait for confirmation.
|
|
||||||
std::cout << "Subscribing to topic: " << TOPIC << std::endl;
|
|
||||||
client.subscribe(TOPIC, 1)->wait(); // Subscribe with QoS level 1
|
|
||||||
|
|
||||||
// Keep the program running to continue receiving messages from the broker.
|
|
||||||
while (true) {
|
|
||||||
std::this_thread::sleep_for(std::chrono::seconds(1)); // Sleep to reduce CPU usage
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (const mqtt::exception &exc) {
|
|
||||||
// Catch any MQTT exceptions and display the error message.
|
|
||||||
std::cerr << "Error: " << exc.what() << std::endl;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0; // Return 0 to indicate successful execution
|
|
||||||
}
|
|
44
src/C++/OpenCV/CMakeLists.txt
Normal file
44
src/C++/OpenCV/CMakeLists.txt
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
cmake_minimum_required( VERSION 3.6 )
|
||||||
|
|
||||||
|
# Require C++11 (or later)
|
||||||
|
set( CMAKE_CXX_STANDARD 23 )
|
||||||
|
set( CMAKE_CXX_STANDARD_REQUIRED ON )
|
||||||
|
set( CMAKE_CXX_EXTENSIONS OFF )
|
||||||
|
set(BUILD_MODE Debug)
|
||||||
|
# Create Project
|
||||||
|
project( Sample )
|
||||||
|
add_executable( YOLOv4 util.h main.cpp )
|
||||||
|
|
||||||
|
# Set StartUp Project
|
||||||
|
set_property( DIRECTORY PROPERTY VS_STARTUP_PROJECT "YOLOv4" )
|
||||||
|
|
||||||
|
# Find Package
|
||||||
|
# OpenCV
|
||||||
|
find_package( OpenCV REQUIRED )
|
||||||
|
|
||||||
|
if( OpenCV_FOUND )
|
||||||
|
# Additional Include Directories
|
||||||
|
include_directories( ${OpenCV_INCLUDE_DIRS} )
|
||||||
|
|
||||||
|
# Additional Dependencies
|
||||||
|
target_link_libraries( YOLOv4 ${OpenCV_LIBS} )
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Download Model
|
||||||
|
set( MODEL https://github.com/AlexeyAB/darknet/releases/download/darknet_yolo_v3_optimal/yolov4.weights )
|
||||||
|
file( DOWNLOAD
|
||||||
|
"${MODEL}"
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/yolov4.weights"
|
||||||
|
EXPECTED_HASH SHA256=e8a4f6c62188738d86dc6898d82724ec0964d0eb9d2ae0f0a9d53d65d108d562
|
||||||
|
SHOW_PROGRESS
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# Download Config
|
||||||
|
set( CONFIG https://raw.githubusercontent.com/AlexeyAB/darknet/master/cfg/yolov4.cfg )
|
||||||
|
file( DOWNLOAD
|
||||||
|
"${CONFIG}"
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/yolov4.cfg"
|
||||||
|
EXPECTED_HASH SHA256=a6d0f8e5c62cc8378384f75a8159b95fa2964d4162e33351b00ac82e0fc46a34
|
||||||
|
SHOW_PROGRESS
|
||||||
|
)
|
BIN
src/C++/OpenCV/YOLOv4
Executable file
BIN
src/C++/OpenCV/YOLOv4
Executable file
Binary file not shown.
80
src/C++/OpenCV/coco.names
Normal file
80
src/C++/OpenCV/coco.names
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
person
|
||||||
|
bicycle
|
||||||
|
car
|
||||||
|
motorbike
|
||||||
|
aeroplane
|
||||||
|
bus
|
||||||
|
train
|
||||||
|
truck
|
||||||
|
boat
|
||||||
|
traffic light
|
||||||
|
fire hydrant
|
||||||
|
stop sign
|
||||||
|
parking meter
|
||||||
|
bench
|
||||||
|
bird
|
||||||
|
cat
|
||||||
|
dog
|
||||||
|
horse
|
||||||
|
sheep
|
||||||
|
cow
|
||||||
|
elephant
|
||||||
|
bear
|
||||||
|
zebra
|
||||||
|
giraffe
|
||||||
|
backpack
|
||||||
|
umbrella
|
||||||
|
handbag
|
||||||
|
tie
|
||||||
|
suitcase
|
||||||
|
frisbee
|
||||||
|
skis
|
||||||
|
snowboard
|
||||||
|
sports ball
|
||||||
|
kite
|
||||||
|
baseball bat
|
||||||
|
baseball glove
|
||||||
|
skateboard
|
||||||
|
surfboard
|
||||||
|
tennis racket
|
||||||
|
bottle
|
||||||
|
wine glass
|
||||||
|
cup
|
||||||
|
fork
|
||||||
|
knife
|
||||||
|
spoon
|
||||||
|
bowl
|
||||||
|
banana
|
||||||
|
apple
|
||||||
|
sandwich
|
||||||
|
orange
|
||||||
|
broccoli
|
||||||
|
carrot
|
||||||
|
hot dog
|
||||||
|
pizza
|
||||||
|
donut
|
||||||
|
cake
|
||||||
|
chair
|
||||||
|
sofa
|
||||||
|
pottedplant
|
||||||
|
bed
|
||||||
|
diningtable
|
||||||
|
toilet
|
||||||
|
tvmonitor
|
||||||
|
laptop
|
||||||
|
mouse
|
||||||
|
remote
|
||||||
|
keyboard
|
||||||
|
cell phone
|
||||||
|
microwave
|
||||||
|
oven
|
||||||
|
toaster
|
||||||
|
sink
|
||||||
|
refrigerator
|
||||||
|
book
|
||||||
|
clock
|
||||||
|
vase
|
||||||
|
scissors
|
||||||
|
teddy bear
|
||||||
|
hair drier
|
||||||
|
toothbrush
|
209
src/C++/OpenCV/main.cpp
Normal file
209
src/C++/OpenCV/main.cpp
Normal file
@@ -0,0 +1,209 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <opencv2/opencv.hpp>
|
||||||
|
#include <opencv2/dnn.hpp>
|
||||||
|
#include <filesystem>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
// Helper function to check if a file exists
|
||||||
|
bool fileExists(const std::string &path)
|
||||||
|
{
|
||||||
|
return std::filesystem::exists(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to read class names from a file
|
||||||
|
std::vector<std::string> _readClassNameList(const std::string &path)
|
||||||
|
{
|
||||||
|
std::vector<std::string> classes;
|
||||||
|
|
||||||
|
// Check if file exists
|
||||||
|
if (!fileExists(path))
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Class names file not found: " + path);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to open and read file
|
||||||
|
std::ifstream file(path);
|
||||||
|
if (!file.is_open())
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Unable to open class names file: " + path);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string line;
|
||||||
|
while (std::getline(file, line))
|
||||||
|
{
|
||||||
|
if (!line.empty())
|
||||||
|
{
|
||||||
|
classes.push_back(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (classes.empty())
|
||||||
|
{
|
||||||
|
throw std::runtime_error("No classes found in file: " + path);
|
||||||
|
}
|
||||||
|
|
||||||
|
return classes;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Open Video Capture
|
||||||
|
cv::VideoCapture capture = cv::VideoCapture(0);
|
||||||
|
if (!capture.isOpened())
|
||||||
|
{
|
||||||
|
std::cerr << "Failed to open camera device" << std::endl;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read Class Name List and Color Table
|
||||||
|
const std::string list = "coco.names";
|
||||||
|
const std::vector<std::string> classes = _readClassNameList(list);
|
||||||
|
const std::vector<cv::Scalar> colors = getClassColors(classes.size());
|
||||||
|
|
||||||
|
// Debug: Print the size of the colors vector
|
||||||
|
std::cout << "Number of colors: " << colors.size() << std::endl;
|
||||||
|
|
||||||
|
// Read Darknet
|
||||||
|
const std::string model = "yolov4.weights";
|
||||||
|
const std::string config = "yolov4.cfg";
|
||||||
|
cv::dnn::Net net = cv::dnn::readNet(model, config);
|
||||||
|
if (net.empty())
|
||||||
|
{
|
||||||
|
std::cerr << "Failed to load network" << std::endl;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set Preferable Backend
|
||||||
|
net.setPreferableBackend(cv::dnn::DNN_BACKEND_OPENCV);
|
||||||
|
|
||||||
|
// Set Preferable Target
|
||||||
|
net.setPreferableTarget(cv::dnn::DNN_TARGET_OPENCL);
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
// Read Frame
|
||||||
|
cv::Mat frame;
|
||||||
|
capture >> frame;
|
||||||
|
if (frame.empty())
|
||||||
|
{
|
||||||
|
cv::waitKey(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (frame.channels() == 4)
|
||||||
|
{
|
||||||
|
cv::cvtColor(frame, frame, cv::COLOR_BGRA2BGR);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create Blob from Input Image
|
||||||
|
cv::Mat blob = cv::dnn::blobFromImage(frame, 1 / 255.f, cv::Size(416, 416), cv::Scalar(), true, false);
|
||||||
|
|
||||||
|
// Set Input Blob
|
||||||
|
net.setInput(blob);
|
||||||
|
|
||||||
|
// Run Forward Network
|
||||||
|
std::vector<cv::Mat> detections;
|
||||||
|
net.forward(detections, getOutputsNames(net));
|
||||||
|
|
||||||
|
// Draw Region
|
||||||
|
std::vector<int32_t> class_ids;
|
||||||
|
std::vector<float> confidences;
|
||||||
|
std::vector<cv::Rect> rectangles;
|
||||||
|
for (cv::Mat &detection : detections)
|
||||||
|
{
|
||||||
|
if (detection.empty())
|
||||||
|
{
|
||||||
|
std::cerr << "Detection matrix is empty!" << std::endl;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (int32_t i = 0; i < detection.rows; i++)
|
||||||
|
{
|
||||||
|
cv::Mat region = detection.row(i);
|
||||||
|
|
||||||
|
// Retrieve Max Confidence and Class Index
|
||||||
|
cv::Mat scores = region.colRange(5, detection.cols);
|
||||||
|
cv::Point class_id;
|
||||||
|
double confidence;
|
||||||
|
cv::minMaxLoc(scores, 0, &confidence, 0, &class_id);
|
||||||
|
|
||||||
|
// Check Confidence
|
||||||
|
constexpr float threshold = 0.2;
|
||||||
|
if (threshold > confidence)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve Object Position
|
||||||
|
const int32_t x_center = static_cast<int32_t>(region.at<float>(0) * frame.cols);
|
||||||
|
const int32_t y_center = static_cast<int32_t>(region.at<float>(1) * frame.rows);
|
||||||
|
const int32_t width = static_cast<int32_t>(region.at<float>(2) * frame.cols);
|
||||||
|
const int32_t height = static_cast<int32_t>(region.at<float>(3) * frame.rows);
|
||||||
|
const cv::Rect rectangle = cv::Rect(x_center - (width / 2), y_center - (height / 2), width, height);
|
||||||
|
|
||||||
|
// Add Class ID, Confidence, Rectangle
|
||||||
|
class_ids.push_back(class_id.x);
|
||||||
|
confidences.push_back(confidence);
|
||||||
|
rectangles.push_back(rectangle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove Overlap Rectangles using Non-Maximum Suppression
|
||||||
|
constexpr float confidence_threshold = 0.5; // Confidence
|
||||||
|
constexpr float nms_threshold = 0.5; // IoU (Intersection over Union)
|
||||||
|
std::vector<int32_t> indices;
|
||||||
|
cv::dnn::NMSBoxes(rectangles, confidences, confidence_threshold, nms_threshold, indices);
|
||||||
|
|
||||||
|
// Draw Rectangle
|
||||||
|
for (const int32_t &index : indices)
|
||||||
|
{
|
||||||
|
// Bounds checking
|
||||||
|
if (class_ids[index] >= colors.size())
|
||||||
|
{
|
||||||
|
std::cerr << "Color index out of bounds: " << class_ids[index] << " (max: " << colors.size() - 1 << ")" << std::endl;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const cv::Rect rectangle = rectangles[index];
|
||||||
|
const cv::Scalar color = colors[class_ids[index]];
|
||||||
|
|
||||||
|
// Debug: Print the index and color
|
||||||
|
std::cout << "Drawing rectangle with color index: " << class_ids[index] << std::endl;
|
||||||
|
|
||||||
|
constexpr int32_t thickness = 3;
|
||||||
|
cv::rectangle(frame, rectangle, color, thickness);
|
||||||
|
|
||||||
|
std::string label = classes[class_ids[index]] + ": " + std::to_string(static_cast<int>(confidences[index] * 100)) + "%";
|
||||||
|
|
||||||
|
int baseLine;
|
||||||
|
cv::Size labelSize = cv::getTextSize(label, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine);
|
||||||
|
int top = std::max(rectangle.y, labelSize.height);
|
||||||
|
cv::rectangle(frame, cv::Point(rectangle.x, top - labelSize.height),
|
||||||
|
cv::Point(rectangle.x + labelSize.width, top + baseLine), color, cv::FILLED);
|
||||||
|
cv::putText(frame, label, cv::Point(rectangle.x, top), cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(255, 255, 255), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show Image
|
||||||
|
cv::imshow("Object Detection", frame);
|
||||||
|
const int32_t key = cv::waitKey(1);
|
||||||
|
if (key == 'q')
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cv::destroyAllWindows();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
catch (const std::exception &e)
|
||||||
|
{
|
||||||
|
std::cerr << "Error: " << e.what() << std::endl;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// cloned and fixed from https://github.com/UnaNancyOwen/OpenCVDNNSample/tree/master
|
61
src/C++/OpenCV/util.h
Normal file
61
src/C++/OpenCV/util.h
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
#ifndef __UTIL__
|
||||||
|
#define __UTIL__
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include <fstream>
|
||||||
|
#include <opencv2/dnn.hpp>
|
||||||
|
#include <opencv2/core.hpp>
|
||||||
|
#include <opencv2/highgui.hpp>
|
||||||
|
|
||||||
|
// Get Output Layers Name
|
||||||
|
std::vector<std::string> getOutputsNames( const cv::dnn::Net& net )
|
||||||
|
{
|
||||||
|
static std::vector<std::string> names;
|
||||||
|
if( names.empty() ){
|
||||||
|
std::vector<int32_t> out_layers = net.getUnconnectedOutLayers();
|
||||||
|
std::vector<std::string> layers_names = net.getLayerNames();
|
||||||
|
names.resize( out_layers.size() );
|
||||||
|
for( size_t i = 0; i < out_layers.size(); ++i ){
|
||||||
|
names[i] = layers_names[out_layers[i] - 1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get Output Layer Type
|
||||||
|
std::string getOutputLayerType( cv::dnn::Net& net )
|
||||||
|
{
|
||||||
|
const std::vector<int32_t> out_layers = net.getUnconnectedOutLayers();
|
||||||
|
const std::string output_layer_type = net.getLayer( out_layers[0] )->type;
|
||||||
|
return output_layer_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read Class Name List
|
||||||
|
std::vector<std::string> readClassNameList( const std::string list_path )
|
||||||
|
{
|
||||||
|
std::vector<std::string> classes;
|
||||||
|
std::ifstream ifs( list_path );
|
||||||
|
if( !ifs.is_open() ){
|
||||||
|
return classes;
|
||||||
|
}
|
||||||
|
std::string class_name = "";
|
||||||
|
while( std::getline( ifs, class_name ) ){
|
||||||
|
classes.push_back( class_name );
|
||||||
|
}
|
||||||
|
return classes;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get Class Color Table for Visualize
|
||||||
|
std::vector<cv::Scalar> getClassColors( const int32_t number_of_colors )
|
||||||
|
{
|
||||||
|
cv::RNG random;
|
||||||
|
std::vector<cv::Scalar> colors;
|
||||||
|
for( int32_t i = 0; i < number_of_colors; i++ ){
|
||||||
|
cv::Scalar color( random.uniform( 0, 255 ), random.uniform( 0, 255 ), random.uniform( 0, 255 ) );
|
||||||
|
colors.push_back( color );
|
||||||
|
}
|
||||||
|
return colors;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __UTIL__
|
1158
src/C++/OpenCV/yolov4.cfg
Normal file
1158
src/C++/OpenCV/yolov4.cfg
Normal file
File diff suppressed because it is too large
Load Diff
BIN
src/C++/OpenCV/yolov4.weights
Normal file
BIN
src/C++/OpenCV/yolov4.weights
Normal file
Binary file not shown.
@@ -1,18 +1,24 @@
|
|||||||
from flask import Flask, request, render_template, jsonify
|
from flask import Flask, Response, request, render_template, jsonify
|
||||||
import paho.mqtt.client as mqtt
|
import paho.mqtt.client as mqtt
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
|
|
||||||
|
kobuki_message = "empty"
|
||||||
def on_message(client, userdata, message):
|
def on_message(client, userdata, message):
|
||||||
global kobuki_message #set scope for this variable
|
global kobuki_message, latest_image
|
||||||
kobuki_message = str(message.payload.decode("utf-8"))
|
if message.topic == "kobuki/data":
|
||||||
|
kobuki_message = str(message.payload.decode("utf-8"))
|
||||||
|
elif message.topic == "kobuki/cam":
|
||||||
|
latest_image = message.payload
|
||||||
|
|
||||||
# Create an MQTT client instance
|
# Create an MQTT client instance
|
||||||
mqtt_client = mqtt.Client()
|
mqtt_client = mqtt.Client()
|
||||||
mqtt_client.username_pw_set("ishak", "kobuki")
|
mqtt_client.username_pw_set("server", "serverwachtwoordofzo")
|
||||||
mqtt_client.connect("localhost", 1883, 60)
|
mqtt_client.connect("localhost", 80, 60)
|
||||||
mqtt_client.loop_start()
|
mqtt_client.loop_start()
|
||||||
mqtt_client.subscribe("kobuki/data")
|
mqtt_client.subscribe("kobuki/data")
|
||||||
|
mqtt_client.subscribe("kobuki/cam")
|
||||||
|
|
||||||
mqtt_client.on_message = on_message # this lines needs to be under the function definition otherwise it cant find which function it needs to use
|
mqtt_client.on_message = on_message # this lines needs to be under the function definition otherwise it cant find which function it needs to use
|
||||||
|
|
||||||
@app.route('/')
|
@app.route('/')
|
||||||
@@ -44,6 +50,21 @@ def data():
|
|||||||
return kobuki_message
|
return kobuki_message
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/image')
|
||||||
|
def image():
|
||||||
|
global latest_image
|
||||||
|
if latest_image is not None:
|
||||||
|
return Response(latest_image, mimetype='image/jpeg')
|
||||||
|
else:
|
||||||
|
return "No image available", 404
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/phpmyadmin/<path:path>')
|
||||||
|
def phpmyadmin_passthrough(path):
|
||||||
|
# Laat Apache deze route direct afhandelen
|
||||||
|
return "", 404
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
BIN
src/Python/flask/web/static/images/logo.png
Normal file
BIN
src/Python/flask/web/static/images/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 200 KiB |
@@ -1,24 +1,25 @@
|
|||||||
// Selecteer alle knoppen en voeg een event listener toe aan elke knop
|
document.addEventListener("DOMContentLoaded", function() {
|
||||||
document.querySelectorAll(".btn").forEach(button => {
|
document.querySelectorAll(".btn").forEach(button => {
|
||||||
button.addEventListener("click", function(event) {
|
button.addEventListener("click", function(event) {
|
||||||
event.preventDefault(); // voorkomt pagina-verversing
|
event.preventDefault(); // prevents page refresh
|
||||||
|
|
||||||
// Haal de waarde van de knop op
|
// Get the value of the button
|
||||||
const direction = event.target.value;
|
const direction = event.target.value;
|
||||||
|
|
||||||
fetch("/move", {
|
fetch("/move", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json"
|
"Content-Type": "application/json"
|
||||||
},
|
},
|
||||||
body: JSON.stringify({ direction: direction })
|
body: JSON.stringify({ direction: direction })
|
||||||
})
|
})
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(data => {
|
.then(data => {script
|
||||||
console.log("Success:", data);
|
console.log("Success:", data);
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
console.error("Error:", error);
|
console.error("Error:", error);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -34,7 +35,7 @@ document.querySelectorAll(".btn").forEach(button => {
|
|||||||
const data = await fetchData();
|
const data = await fetchData();
|
||||||
const sensorDataContainer = document.getElementById("sensor-data");
|
const sensorDataContainer = document.getElementById("sensor-data");
|
||||||
sensorDataContainer.innerHTML = ""; // Clear previous data
|
sensorDataContainer.innerHTML = ""; // Clear previous data
|
||||||
//for each object in json array create a new paragraph element and append it to the sensorDataContainer
|
// For each object in JSON array, create a new paragraph element and append it to the sensorDataContainer
|
||||||
for (const [key, value] of Object.entries(data)) {
|
for (const [key, value] of Object.entries(data)) {
|
||||||
const dataElement = document.createElement("p");
|
const dataElement = document.createElement("p");
|
||||||
dataElement.textContent = `${key}: ${value}`;
|
dataElement.textContent = `${key}: ${value}`;
|
||||||
@@ -42,6 +43,15 @@ document.querySelectorAll(".btn").forEach(button => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update the image
|
||||||
|
function updateImage() {
|
||||||
|
var img = document.getElementById("robot-image");
|
||||||
|
img.src = "/image?" + new Date().getTime(); // Add timestamp to avoid caching
|
||||||
|
}
|
||||||
|
|
||||||
// Fetch and display sensor data every 5 seconds
|
// Fetch and display sensor data every 5 seconds
|
||||||
setInterval(parseData, 5000);
|
setInterval(parseData, 1000);
|
||||||
|
|
||||||
|
// Update the image every 5 seconds
|
||||||
|
setInterval(updateImage, 200);
|
||||||
});
|
});
|
@@ -23,6 +23,22 @@ body {
|
|||||||
right: 0%;
|
right: 0%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.footer{
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
max-width: 80%;
|
||||||
|
background-color: #fff;
|
||||||
|
border: 1px solid #f0f0f0;
|
||||||
|
border-radius: 50px;
|
||||||
|
align-items: center;
|
||||||
|
margin: 1.5rem auto 0 auto;
|
||||||
|
padding: 0 30px;
|
||||||
|
top: 0%;
|
||||||
|
bottom: auto;
|
||||||
|
left: 0%;
|
||||||
|
right: 0%;
|
||||||
|
}
|
||||||
|
|
||||||
.imgNav {
|
.imgNav {
|
||||||
height: 50px;
|
height: 50px;
|
||||||
border-radius: 20px;
|
border-radius: 20px;
|
||||||
@@ -73,6 +89,18 @@ body {
|
|||||||
transition: transform 0.2s ease, background-color 0.2s ease;
|
transition: transform 0.2s ease, background-color 0.2s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.text{
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image{
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sectionHeight{
|
||||||
|
height: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
/* Direction buttons */
|
/* Direction buttons */
|
||||||
.btn:nth-child(1) {
|
.btn:nth-child(1) {
|
||||||
/* Left */
|
/* Left */
|
||||||
@@ -139,4 +167,4 @@ th,td {
|
|||||||
th {
|
th {
|
||||||
background-color: #f2f2f2;
|
background-color: #f2f2f2;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
@@ -43,16 +43,6 @@ section h2 {
|
|||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
footer {
|
|
||||||
background-color: #333;
|
|
||||||
color: #fff;
|
|
||||||
text-align: center;
|
|
||||||
padding: 1rem 0;
|
|
||||||
position: fixed;
|
|
||||||
width: 100%;
|
|
||||||
bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
form {
|
form {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
@@ -8,8 +8,9 @@
|
|||||||
{% block head %}{% endblock %}
|
{% block head %}{% endblock %}
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
{% include 'navbar.html' %}
|
{% include 'navbar.html' %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
@@ -1,6 +1,8 @@
|
|||||||
{% extends 'base.html' %} {% block head %}
|
{% extends 'base.html' %}
|
||||||
|
{% block head %}
|
||||||
<link rel="stylesheet" href="../static/style.css" />
|
<link rel="stylesheet" href="../static/style.css" />
|
||||||
{% endblock %} {% block content %}
|
{% endblock %}
|
||||||
|
{% block content %}
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
@@ -11,8 +13,8 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="image-section">
|
<div class="robot-image">
|
||||||
<img src="kobuki.jpg" alt="Kobuki Robot" id="robot-image" />
|
<img src="/image" alt="Kobuki Camera Feed" id="robot-image" />
|
||||||
</div>
|
</div>
|
||||||
<div class="button-section">
|
<div class="button-section">
|
||||||
<form id="form" action="/move" method="post">
|
<form id="form" action="/move" method="post">
|
||||||
@@ -42,7 +44,8 @@
|
|||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="../static/script.js"></script>
|
<script src="../static/script.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
{% endblock %}
|
{% endblock %}
|
21
src/Python/flask/web/templates/footer.html
Normal file
21
src/Python/flask/web/templates/footer.html
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Document</title>
|
||||||
|
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<footer class="footer">
|
||||||
|
<img src="{{url_for('static', filename='images/logo_kobuki.png')}}" alt="logo" class="imgNav" />
|
||||||
|
<h3>© 2024 Kobuki Robot Project. All rights reserved.</h3>
|
||||||
|
<div class="buttonContainer">
|
||||||
|
<a href="{{ url_for('control') }}" target="_blank">
|
||||||
|
<button class="click connectButton">Controller</button>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
@@ -1,58 +1,58 @@
|
|||||||
|
{% extends 'base.html' %} {% block head %}
|
||||||
|
<link rel="stylesheet" href="../static/style.css" />
|
||||||
|
{% endblock %} {% block content %}
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Kobuki Robot Project</title>
|
<title>Kobuki Robot Project</title>
|
||||||
<link rel="stylesheet" href="../static/styleIndex.css" />
|
<link rel="stylesheet" href="../static/style.css" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header>
|
<section class="container sectionHeight">
|
||||||
<h1>Welcome to the Kobuki Robot Project</h1>
|
<p class="text">
|
||||||
<nav>
|
The Kobuki Robot Project is an innovative initiative aimed at developing
|
||||||
<ul>
|
a versatile and intelligent robot platform. Our goal is to create a
|
||||||
<li><a href="#home">Home</a></li>
|
robot that can navigate autonomously, interact with its environment, and
|
||||||
<li><a href="#about">About</a></li>
|
perform various tasks.
|
||||||
<li><a href="#contact">Contact</a></li>
|
</p>
|
||||||
</ul>
|
<img src="{{url_for('static', filename='images/logo.png')}}" alt="logo" class="image" />
|
||||||
</nav>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<section id="home">
|
|
||||||
<h2>Introduction</h2>
|
|
||||||
<p>The Kobuki Robot Project is an innovative initiative aimed at developing a versatile and intelligent robot platform. Our goal is to create a robot that can navigate autonomously, interact with its environment, and perform various tasks.</p>
|
|
||||||
<img src="static/kobuki.jpg" alt="Kobuki Robot">
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section id="about">
|
<section class="container sectionHeight" id="about">
|
||||||
<h2>About the Project</h2>
|
<h2>About the Project</h2>
|
||||||
<p>This project is a collaborative effort involving engineers, researchers, and enthusiasts. The Kobuki robot is equipped with various sensors, including bumpers, cliff sensors, and gyroscopes, to help it navigate and interact with its surroundings.</p>
|
<p>
|
||||||
<p>Key features of the Kobuki Robot:</p>
|
This project is a collaborative effort involving engineers, researchers,
|
||||||
<ul>
|
and enthusiasts. The Kobuki robot is equipped with various sensors,
|
||||||
<li>Autonomous navigation</li>
|
including bumpers, cliff sensors, and gyroscopes, to help it navigate
|
||||||
<li>Obstacle detection and avoidance</li>
|
and interact with its surroundings.
|
||||||
<li>Real-time data processing</li>
|
</p>
|
||||||
<li>Remote control and monitoring</li>
|
<p>Key features of the Kobuki Robot:</p>
|
||||||
</ul>
|
<ul>
|
||||||
|
<li>Autonomous navigation</li>
|
||||||
|
<li>Obstacle detection and avoidance</li>
|
||||||
|
<li>Real-time data processing</li>
|
||||||
|
<li>Remote control and monitoring</li>
|
||||||
|
</ul>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section id="contact">
|
<section class="container" id="contact">
|
||||||
<h2>Contact Us</h2>
|
<h2>Contact Us</h2>
|
||||||
<form id="contact-form" action="/contact" method="post">
|
<form id="contact-form" action="/contact" method="post">
|
||||||
<label for="name">Name:</label>
|
<label for="name">Name:</label>
|
||||||
<input type="text" id="name" name="name" required>
|
<input type="text" id="name" name="name" required />
|
||||||
<label for="email">Email:</label>
|
<label for="email">Email:</label>
|
||||||
<input type="email" id="email" name="email" required>
|
<input type="email" id="email" name="email" required />
|
||||||
<label for="message">Message:</label>
|
<label for="message">Message:</label>
|
||||||
<textarea id="message" name="message" required></textarea>
|
<textarea id="message" name="message" required></textarea>
|
||||||
<button type="submit">Send</button>
|
<button type="submit">Send</button>
|
||||||
</form>
|
</form>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<footer>
|
{% include 'footer.html' %}
|
||||||
<p>© 2023 Kobuki Robot Project. All rights reserved.</p>
|
|
||||||
</footer>
|
|
||||||
|
|
||||||
<script src="static/script.js"></script>
|
<script src="static/script.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
{% endblock %}
|
||||||
|
@@ -11,13 +11,9 @@
|
|||||||
<img src="{{url_for('static', filename='images/logo_kobuki.png')}}" alt="logo" class="imgNav" />
|
<img src="{{url_for('static', filename='images/logo_kobuki.png')}}" alt="logo" class="imgNav" />
|
||||||
<h3>Kobuki</h3>
|
<h3>Kobuki</h3>
|
||||||
<div class="buttonContainer">
|
<div class="buttonContainer">
|
||||||
<a
|
<a href="{{ url_for('control') }}" target="_blank">
|
||||||
href="https://gitlab.fdmci.hva.nl/propedeuse-hbo-ict/onderwijs/2023-2024/out-a-se-ti/blok-3/vuupoofeehoo27"
|
<button class="click connectButton">Controller</button>
|
||||||
target="_blank"
|
|
||||||
>
|
|
||||||
<button class="click connectButton">Placeholder</button>
|
|
||||||
</a>
|
</a>
|
||||||
<!-- <a href="./signup.html">sign in</a> -->
|
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
|
7
src/Python/wsgi.py
Normal file
7
src/Python/wsgi.py
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
import sys
|
||||||
|
import logging
|
||||||
|
|
||||||
|
logging.basicConfig(stream=sys.stderr)
|
||||||
|
sys.path.insert(0, "/home/ishak/rooziinuubii79/src/Python/flask/web")
|
||||||
|
|
||||||
|
from app import app as application
|
7
src/config/mosquitto.conf
Normal file
7
src/config/mosquitto.conf
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
allow_anonymous false
|
||||||
|
password_file /etc/mosquitto/passwordfile
|
||||||
|
listener 8080
|
||||||
|
protocol websockets
|
||||||
|
|
||||||
|
listener 1884
|
||||||
|
protocol mqtt
|
22
src/config/nginx-sites.conf
Normal file
22
src/config/nginx-sites.conf
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name 145.92.224.21;
|
||||||
|
|
||||||
|
# Proxy WebSocket connections for MQTT
|
||||||
|
location /ws/ {
|
||||||
|
proxy_pass http://localhost:9001;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Proxy HTTP connections for Flask
|
||||||
|
location / {
|
||||||
|
proxy_pass http://localhost:5000;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
}
|
||||||
|
}
|
7
src/config/nginx.conf
Normal file
7
src/config/nginx.conf
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
stream {
|
||||||
|
server {
|
||||||
|
listen 9001;
|
||||||
|
proxy_pass localhost:8080;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
42
teamdocumentatie/Ishak/hoofd-deelvraag.md
Normal file
42
teamdocumentatie/Ishak/hoofd-deelvraag.md
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
# Hoofd en deelvragen
|
||||||
|
|
||||||
|
**Wat is de aanleiding?**
|
||||||
|
De aanleiding is de de behoefte aan veilige communicatie tussen apparaten. Dit is belangrijk omdat onbeveiligde dataoverdracht kan leiden tot datalekken.
|
||||||
|
|
||||||
|
**wat is het probleem/behoefte en waaruit blijkt dat?**
|
||||||
|
Het probleem is dat data die tussen apparaten wordt verstuurd kwetsbaar kan zijn. Dit blijkt nadat wij te horen hebben gekregen dat er niet goed was omgegaan met communicatie tussen apparaten.
|
||||||
|
|
||||||
|
**Wie heeft het probleem/behoefte?**
|
||||||
|
ons groepje, maar ook bijvoorbeeld grote bedrijven waar het heel belangrijk is dat data veilig wordt verstuurd zonder dat het in de verkeerde handen valt.
|
||||||
|
|
||||||
|
**Wanneer is het probleem/behoefte ontstaan?**
|
||||||
|
Het probleem is ontstaan nadat wij te horen hebben gekregen dat er niet goed was omgegaan met communicatie tussen apparaten.
|
||||||
|
|
||||||
|
**Waarom is het een probleem?**
|
||||||
|
Het is een probleem omdat onbeveiligde communicatie kan leiden tot datalekken waaronder privacy. Hiermee kunnen bedrijven in de problemen komen.
|
||||||
|
|
||||||
|
**Waar doet het probleem/behoefte zich voor (afbakening)?**
|
||||||
|
Het probleem komt voor in verschillende sectoren waar data tussen apparaten wordt verstuurd. Dit kan zijn in de zorg, industrie, op kantoor, maar ook met IoT projecten wat je thuis kan hebben.
|
||||||
|
|
||||||
|
## Hoofdvraag
|
||||||
|
|
||||||
|
Welke communicatieprotocol geeft de mogelijkheid om veilig en betrouwbaar te communiceren tussen IoT apparaten?
|
||||||
|
|
||||||
|
## Deelvragen
|
||||||
|
|
||||||
|
1. Wat houdt veilige en betrouwbare communicatie tussen apparaten in?
|
||||||
|
2. Welke protocollen zijn er om veilig en betrouwbaar te communiceren tussen apparaten?
|
||||||
|
3. Wat zijn de voor- en nadelen van de verschillende protocollen?
|
||||||
|
|
||||||
|
## Bronnen
|
||||||
|
|
||||||
|
- Singh, S., & Jyoti. (2024, June 7). Secure Communications Protocols for IoT networks: a survey. https://journal.ijprse.com/index.php/ijprse/article/view/1082
|
||||||
|
- Nguyen, K. T., Laurent, M., Oualha, N., CEA, & Institut Mines-Telecom. (2015). Survey on secure communication protocols for the Internet of Things. In Ad Hoc Networks (Vol. 32, pp. 17–31) [Journal-article]. http://dx.doi.org/10.1016/j.adhoc.2015.01.006
|
||||||
|
- Miorandi, D., Sicari, S., De Pellegrini, F., & Imrich Chlamtac. (2012). Internet of things: Vision, applications and research challenges. In Ad Hoc Networks (Vol. 10, pp. 1497–1516) [Journal-article]. Elsevier B.V. http://dx.doi.org/10.1016/j.adhoc.2012.02.016
|
||||||
|
- Christiano, P. (2023, November 5). Top 9 IoT communication protocols & their features in 2024: An In-Depth guide - ExpertBeacon. Expertbeacon. https://expertbeacon.com/iot-communication-protocol/
|
||||||
|
- Yugha, R., & Chithra, S. (2020). A survey on technologies and security protocols: Reference for future generation IoT. Journal of Network and Computer Applications, 169, 102763. https://doi.org/10.1016/j.jnca.2020.102763
|
||||||
|
- De Mendizábal, I. (2022, June 16). IoT Communication Protocols—IoT Data Protocols. Technical Articles. https://www.allaboutcircuits.com/technical-articles/internet-of-things-communication-protocols-iot-data-protocols/
|
||||||
|
- IoT-technologieën en -protocollen | Microsoft Azure. (n.d.). https://azure.microsoft.com/nl-nl/solutions/iot/iot-technology-protocols
|
||||||
|
- Het IoT verbinden: wat is MQTT en waarin verschilt het van CoAP? (n.d.). https://www.onlogic.com/nl/blog/het-iot-verbinden-wat-is-mqtt-en-waarin-verschilt-het-van-coap/
|
||||||
|
- Nader, K. (2023, October 30). Wat zijn de voordelen van het gebruik van WebSocket voor IoT-communicatie? AppMaster - Ultimate All-in No-code Platform. https://appmaster.io/nl/blog/websocket-voor-iot-communicatie
|
||||||
|
- Sidna, J., Amine, B., Abdallah, N., & Alami, H. E. (2020). Analysis and evaluation of communication Protocols for IoT Applications. Karbala International Journal of Modern Science. https://doi.org/10.1145/3419604.3419754
|
BIN
teamdocumentatie/Ishak/hoofd-deelvraag.pdf
Normal file
BIN
teamdocumentatie/Ishak/hoofd-deelvraag.pdf
Normal file
Binary file not shown.
Reference in New Issue
Block a user