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
8 Commits
OpenCV
...
61651a9a02
Author | SHA1 | Date | |
---|---|---|---|
|
61651a9a02 | ||
|
e5881f1b37 | ||
50b6b83299 | |||
10597ba37d | |||
6ab5716797 | |||
50b90e461f | |||
2811036595 | |||
58f1a931a6 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -32,3 +32,4 @@ Makefile
|
||||
CMakeCache.txt
|
||||
cmake_install.cmake
|
||||
src/C++/OpenCV/main
|
||||
.vs
|
50
docs/code/Mqtt.md
Normal file
50
docs/code/Mqtt.md
Normal file
@@ -0,0 +1,50 @@
|
||||
# MQTT
|
||||
|
||||
## What is MQTT?
|
||||
MQTT is a lightweight messaging protocol made for IOT devices. It allows efficient communication between IoT devices, servers, and applications by allowing them to
|
||||
publish and subscribe to messages.
|
||||
|
||||
|
||||
## How to connect
|
||||
To connect to a MQTT server you need to create a instance of the class.
|
||||
|
||||
Example:
|
||||
```cpp
|
||||
// server adress, Client ID, Client Username, Client Password
|
||||
MqttClient client("ws://145.92.224.21/ws/", "KobukiRPI", "rpi", "rpiwachtwoordofzo"); // create a client object
|
||||
```
|
||||
Later in the setup function you need to call ```client.connect();``` to connect to the mqtt server.
|
||||
```cpp
|
||||
client.connect();
|
||||
```
|
||||
|
||||
When you've connected and the instance is initiated you can subscribe to topics or send messages to topics.
|
||||
|
||||
|
||||
## Subscribing and receiving messages
|
||||
Example subscribing to a topic:
|
||||
```cpp
|
||||
void setup(){
|
||||
client.subscribe("home/commands");
|
||||
}
|
||||
```
|
||||
|
||||
Example receiving latest message from a topic:
|
||||
```cpp
|
||||
std::string foo(){
|
||||
std::string latestMqttMessage = "";
|
||||
latestMqttMessage = client.getLastMessage();
|
||||
return latestMqttMessage;
|
||||
}
|
||||
```
|
||||
|
||||
If you want to subscribe to mulitple topics you need to initiate multiple instances of the mqtt class.
|
||||
|
||||
## Publishing messages
|
||||
Example publishing a message:
|
||||
```cpp
|
||||
void foo(std::string Message){
|
||||
//channel, payload
|
||||
client.publishMessage("kobuki/example", Message);
|
||||
}
|
||||
```
|
@@ -1,20 +1,69 @@
|
||||
# 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.
|
||||
|
||||
We want that 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
|
||||
* glew (for openGL)
|
||||
* opencv C++ lib
|
||||
|
||||
How to install OpenCV
|
||||
```bash
|
||||
sudo apt-get install libopencv-dev
|
||||
```
|
||||
|
||||
## Code explanation
|
||||
|
||||
### Opening the camera with OpenCV
|
||||
```cpp
|
||||
VideoCapture cap(0); //Open the default camera (0), points to /dev/video0. You could also change the number to the preferred camera
|
||||
if (!cap.isOpened()) { //if camera is not opened throw a error message
|
||||
cerr << "Error: Could not open camera" << endl;
|
||||
return;
|
||||
}
|
||||
```
|
||||
|
||||
## Taking a picture and storing it in a variable
|
||||
```cpp
|
||||
Mat frame; //create a new Matrix variable called frame
|
||||
while (true) {
|
||||
cap >> frame; // Capture a new image frame.
|
||||
if (frame.empty()) { //if the variable frame is not filled return a error
|
||||
cerr << "Error: Could not capture image" << endl;
|
||||
continue;
|
||||
}
|
||||
```
|
||||
|
||||
## Encoding the image for sending it over MQTT
|
||||
```cpp
|
||||
vector<uchar> buf; //create a dyanmic buffer for the image
|
||||
imencode(".jpg", frame, buf); //encode the image to the buffer
|
||||
auto* enc_msg = reinterpret_cast<unsigned char*>(buf.data());
|
||||
```
|
||||
|
||||
```cpp
|
||||
|
||||
void CapnSend() {
|
||||
|
||||
|
||||
|
||||
|
||||
// Convert the image to a byte array
|
||||
|
||||
|
||||
// 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
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Sources
|
||||
* https://github.com/UnaNancyOwen/OpenCVDNNSample/tree/master
|
25
docs/code/kobuki-driver.md
Normal file
25
docs/code/kobuki-driver.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# Kobuki driver
|
||||
|
||||
## How do i communicate with the kobuki
|
||||
You can communicate with the kobuki by usb serial or the big serial port on the front. We chose the usb port paired with a raspberry Pi.
|
||||
|
||||
The Kobuki sends a message every 200ms with a baudrate of 115200. It sends all the sensordata and the message always starts with the same 2 bytes 0xAA and 0x55.
|
||||
|
||||
## Kobuki payloads
|
||||
To communicate with the kobuki we need to send payloads to the kobuki. These are structured the same as the payloads that the kobuki sends.
|
||||
|
||||
```cpp
|
||||
unsigned char KobukiPayload[11] = {
|
||||
0xaa, // Start byte 1
|
||||
0x55, // Start byte 2
|
||||
0x08, // Payload length (the first 2 bytes dont count)
|
||||
0x01, // payload type (0x01 = control command)
|
||||
0x04, // Control byte or additional identifier
|
||||
actual_speed % 256, // Lower byte of speed value (max actual_speed 1024)
|
||||
actual_speed >> 8, // Upper byte of speed value
|
||||
0x00, // Placeholder for radius
|
||||
0x00, // Placeholder for radius
|
||||
0x00 // Placeholder for checksum (will be applied later)
|
||||
};
|
||||
```
|
||||
You can also find the documentation about the payloads on the kobuki website
|
@@ -592,6 +592,8 @@ void CKobuki::robotSafety() {
|
||||
std::cout << "Safety condition triggered!" << std::endl; // Debug print
|
||||
forward(-100); // reverse the robot
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(static_cast<int>(100)));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -2,6 +2,8 @@
|
||||
#include <iostream>
|
||||
//moet checkenvalue gebruiken of moet kijken naar de payloadlength welke dingen er extra zijn
|
||||
int KobukiParser::parseKobukiMessage(TKobukiData &output, unsigned char *data) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(static_cast<int>(20))); //avoid busy waiting. The kobuki sends a message every 20ms
|
||||
|
||||
int rtrnvalue = checkChecksum(data);
|
||||
if (rtrnvalue != 0) {
|
||||
// std::cerr << "Invalid checksum" << std::endl;
|
||||
|
@@ -2,6 +2,8 @@
|
||||
#define KOBUKIPARSER_H
|
||||
|
||||
#include <vector>
|
||||
#include <thread>
|
||||
|
||||
|
||||
struct TRawGyroData {
|
||||
int x, y, z;
|
||||
|
@@ -36,7 +36,11 @@ int main()
|
||||
std::thread sendMqtt([&]() { sendKobukiData(robot.parser.data); });
|
||||
|
||||
while(true){
|
||||
parseMQTT(readMQTT());
|
||||
std::string message = readMQTT();
|
||||
if (!message.empty()){
|
||||
parseMQTT(message);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
sendMqtt.join();
|
||||
@@ -46,10 +50,13 @@ int main()
|
||||
|
||||
std::string readMQTT()
|
||||
{
|
||||
message = client.getLastMessage();
|
||||
if (!message.empty())
|
||||
static std::string lastMessage;
|
||||
|
||||
std::string message = client.getLastMessage();
|
||||
if (!message.empty() && message != lastMessage)
|
||||
{
|
||||
std::cout << "MQTT Message: " << message << std::endl;
|
||||
lastMessage = message;
|
||||
}
|
||||
|
||||
// Add a small delay to avoid busy-waiting
|
||||
|
@@ -3,7 +3,6 @@ import paho.mqtt.client as mqtt
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
kobuki_message = "empty"
|
||||
def on_message(client, userdata, message):
|
||||
global kobuki_message, latest_image
|
||||
if message.topic == "kobuki/data":
|
||||
@@ -11,10 +10,11 @@ def on_message(client, userdata, message):
|
||||
elif message.topic == "kobuki/cam":
|
||||
latest_image = message.payload
|
||||
|
||||
|
||||
# Create an MQTT client instance
|
||||
mqtt_client = mqtt.Client()
|
||||
mqtt_client.username_pw_set("server", "serverwachtwoordofzo")
|
||||
mqtt_client.connect("localhost", 80, 60)
|
||||
mqtt_client.connect("localhost", 1884, 60)
|
||||
mqtt_client.loop_start()
|
||||
mqtt_client.subscribe("kobuki/data")
|
||||
mqtt_client.subscribe("kobuki/cam")
|
||||
@@ -49,7 +49,6 @@ def move():
|
||||
def data():
|
||||
return kobuki_message
|
||||
|
||||
|
||||
@app.route('/image')
|
||||
def image():
|
||||
global latest_image
|
||||
|
@@ -25,9 +25,12 @@ document.addEventListener("DOMContentLoaded", function() {
|
||||
|
||||
// Fetch data from the server
|
||||
async function fetchData() {
|
||||
try{
|
||||
const response = await fetch("/data");
|
||||
const data = await response.json();
|
||||
return data;
|
||||
} catch (error) {
|
||||
console.error("Error:", error);
|
||||
}
|
||||
|
||||
// Parse the data and show it on the website
|
||||
|
@@ -1,7 +0,0 @@
|
||||
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
|
Reference in New Issue
Block a user