21 Commits

Author SHA1 Message Date
ishak jmilou.ishak
f493665275 riep de functie nergens aan 2025-01-21 16:13:26 +01:00
ishak jmilou.ishak
899aa94b40 seperate yolo results because it updates now only when going to /yolo_results 2025-01-21 16:01:59 +01:00
ishak jmilou.ishak
d5524d7890 shouldn't have done POST 2025-01-21 15:09:23 +01:00
ishak jmilou.ishak
976840c6b2 forgot to do system prune 2025-01-21 14:28:40 +01:00
ishak jmilou.ishak
88364561ea got error when running new docker 2025-01-21 14:27:44 +01:00
ishak jmilou.ishak
64d2aedc3b feat: allow POST method for yolo_results endpoint 2025-01-21 14:16:26 +01:00
ishak jmilou.ishak
6597cb133a checking for error in db input 2025-01-21 14:10:31 +01:00
ishak jmilou.ishak
ec44cb955b feat: implement automatic reconnection for Kobuki when disconnected 2025-01-21 12:29:03 +01:00
ishak jmilou.ishak
c74b9a8758 refactor: use dynamic port detection for Kobuki communication setup 2025-01-21 12:26:41 +01:00
ishak jmilou.ishak
b20b9b693a changed portname to const char 2025-01-21 12:25:06 +01:00
ishak jmilou.ishak
99599a6c21 refactor: change portname parameter to const char* in startCommunication and improve USB device check logic 2025-01-21 12:23:20 +01:00
ishak jmilou.ishak
29ef742a94 fix: use const_cast for port string in Kobuki communication 2025-01-20 15:22:16 +01:00
ishak jmilou.ishak
0e9d9dda68 laat kobuki nu connecten op open ports 2025-01-20 15:18:37 +01:00
ishak jmilou.ishak
2c630bf89b refactor: improve Kobuki connection handling and add USB device check 2025-01-20 12:11:38 +01:00
ishak jmilou.ishak
ef3407b742 refactor: reorder includes and improve code formatting for readability 2025-01-20 11:15:45 +01:00
ishak jmilou.ishak
3d9a68ff7f added else statement 2025-01-20 11:09:12 +01:00
ishak jmilou.ishak
aedff1c2cc made more debug 2025-01-20 10:58:34 +01:00
ishak jmilou.ishak
c31689ac70 Merge branch 'main' of ssh://gitlab.fdmci.hva.nl/technische-informatica-sm3/ti-projectten/rooziinuubii79 2025-01-16 13:55:25 +01:00
ishak jmilou.ishak
1ab718a472 new reconnect function 2025-01-16 13:55:24 +01:00
bbade2384c Merge branch 'usb-reconnect' into 'main'
opencv camera logic rewrite

See merge request technische-informatica-sm3/ti-projectten/rooziinuubii79!5
2025-01-16 12:36:32 +01:00
ishak jmilou.ishak
36aaee9bad removed commented code 2025-01-16 12:15:14 +01:00
3 changed files with 161 additions and 48 deletions

View File

@@ -0,0 +1,78 @@
# Kobuki automatische reconnect
Mijn taak was om de kobuki automatisch te reconnecten als de verbinding verbroken werd met de pi. nu moet je telkens handmatig de pi laten connecten met de kobuki, dit is niet handig als iemand niet weet hoe dit moet.
De connectie word gemaakt met ttyUSB0. Dat is de eerste poort die wij kunnen gebruiken voor de kobuki.
```cpp
robot.startCommunication("/dev/ttyUSB0", true, null_ptr);
```
ik heb een functie gemaakt die kijkt of de pi nog is verbonden aan de kobuki. in de if statement kijkt hij elke 5 seconden of de ttyusb0 poort beschikbaar is.
```cpp
void checkKobukiConnection()
{
while (true)
{
std::lock_guard<std::mutex> lock(connectionMutex);
// Controleer of het apparaat beschikbaar is
if (!std::ifstream("/dev/ttyUSB0")){
if (kobuki_connected){
cout << "Kobuki disconnected: USB device not found." << endl;
kobuki_connected = false;
}
std::this_thread::sleep_for(std::chrono::seconds(5));
continue; // Probeer later opnieuw
}
```
Hier kijk ik dan of de kobuki is geconnect, zoniet dan moet ie weer connecten met ttyUSB0
```cpp
// Controleer of de Kobuki verbonden is
if (!robot.isConnected()){
if (kobuki_connected){
cout << "Kobuki disconnected." << endl;
kobuki_connected = false;
}
cout << "Attempting to reconnect Kobuki..." << endl;
robot.startCommunication("/dev/ttyUSB0", true, nullptr);
if (robot.isConnected()){
cout << "Kobuki reconnected successfully!" << endl;
kobuki_connected = true;
}
else{
cout << "Failed to reconnect Kobuki, retrying in 5 seconds..." << endl;
}
}
```
Nu heb ik het probleem dat als ik de kabel eruit steek en terug in de kobuki stop dat de pi niet meer wil connecten. Dit komt omdat het systeem denkt dat de poort "ttyUSB0" nog steeds gebruikt word. Als ik de kabel dan terug stop word de poort "ttyUSB1" gebruikt, omdat ttyusb0 niet word vrijgegeven.
```bash
ishak@raspberrypi:~ $ dmesg | tail -n 20
[10516.084132] usb 1-1.3: Product: iClebo Kobuki
[10516.084144] usb 1-1.3: Manufacturer: Yujin Robot
[10516.084155] usb 1-1.3: SerialNumber: kobuki_AI02MQMK
[10516.091210] ftdi_sio 1-1.3:1.0: FTDI USB Serial Device converter detected
[10516.091414] usb 1-1.3: Detected FT232R
[10516.099169] usb 1-1.3: FTDI USB Serial Device converter now attached to ttyUSB1
[10574.100491] usb 1-1.3: USB disconnect, device number 34
[10574.101596] ftdi_sio ttyUSB1: FTDI USB Serial Device converter now disconnected from ttyUSB1
[10574.101735] ftdi_sio 1-1.3:1.0: device disconnected
[10579.697816] usb 1-1.3: new full-speed USB device number 35 using dwc_otg
[10579.829776] usb 1-1.3: New USB device found, idVendor=0403, idProduct=6001, bcdDevice= 6.00
[10579.829821] usb 1-1.3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[10579.829836] usb 1-1.3: Product: iClebo Kobuki
[10579.829848] usb 1-1.3: Manufacturer: Yujin Robot
[10579.829860] usb 1-1.3: SerialNumber: kobuki_AI02MQMK
[10579.840148] ftdi_sio 1-1.3:1.0: FTDI USB Serial Device converter detected
[10579.840351] usb 1-1.3: Detected FT232R
[10579.842208] usb 1-1.3: FTDI USB Serial Device converter now attached to ttyUSB1
[10612.745819] hwmon hwmon1: Voltage normalised
[10614.761829] hwmon hwmon1: Undervoltage detected!
```

View File

@@ -1,5 +1,7 @@
#include <iostream> #include <iostream>
#include <thread> #include <thread>
#include <fstream>
#include <filesystem>
#include "MQTT/MqttClient.h" #include "MQTT/MqttClient.h"
#include "KobukiDriver/CKobuki.h" #include "KobukiDriver/CKobuki.h"
#include <opencv4/opencv2/opencv.hpp> #include <opencv4/opencv2/opencv.hpp>
@@ -13,40 +15,34 @@ std::atomic<bool> kobuki_connected(false);
std::string readMQTT(); std::string readMQTT();
void parseMQTT(std::string message); void parseMQTT(std::string message);
void CapnSend(); void CapnSend();
void checkKobukiConnection();
// ip, clientID, username, password // ip, clientID, username, password
MqttClient client("ws://145.92.224.21/ws/", "KobukiRPI", "rpi", "rpiwachtwoordofzo"); // create a client object 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);
void setup() std::string findKobukiPort()
{ {
unsigned char *null_ptr(0); for (const auto& entry : std::filesystem::directory_iterator("/dev"))
robot.startCommunication("/dev/ttyUSB0", true, null_ptr); {
// connect mqtt server and sub to commands std::string device = entry.path().string();
if (device.find("ttyUSB") != std::string::npos)
client.connect(); {
client.subscribe("home/commands"); return device; // Returneer de eerste gevonden poort
}
}
return ""; // Geen poort gevonden
} }
void checkKobukiConnection() void setup()
{ {
while (true) std::string port = findKobukiPort();
{ unsigned char *null_ptr(0);
bool connected = robot.isConnected(); robot.startCommunication(const_cast<char*>(port.c_str()), true, null_ptr);
if (!connected && kobuki_connected) // connect mqtt server and sub to commands
{ client.connect();
cout << "Kobuki is disconnected" << endl; client.subscribe("home/commands");
kobuki_connected = false;
}
else if (connected && !kobuki_connected)
{
cout << "Kobuki is connecting..." << endl;
// Start de Kobuki automatisch
robot.startCommunication("/dev/ttyUSB0", true, nullptr);
}
std::this_thread::sleep_for(std::chrono::seconds(5)); // Controleer elke 5 seconden
}
} }
int main() int main()
@@ -55,6 +51,9 @@ int main()
std::thread image(CapnSend); 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); });
std::thread connectionChecker(checkKobukiConnection);
connectionChecker.detach(); // Laat deze thread onafhankelijk draaien
while (true) while (true)
{ {
@@ -70,6 +69,47 @@ int main()
image.join(); image.join();
} }
std::mutex connectionMutex;
void checkKobukiConnection()
{
while (true)
{
std::lock_guard<std::mutex> lock(connectionMutex);
std::string port = findKobukiPort();
if (port.empty()) {
if (kobuki_connected) {
cout << "Kobuki disconnected: No USB device found." << endl;
kobuki_connected = false;
}
std::this_thread::sleep_for(std::chrono::seconds(5));
continue; // Probeer later opnieuw
}
// Controleer of de Kobuki verbonden is
if (!robot.isConnected()){
if (kobuki_connected){
cout << "Kobuki disconnected." << endl;
kobuki_connected = false;
}
cout << "Attempting to reconnect Kobuki..." << endl;
robot.startCommunication(const_cast<char*>(port.c_str()), true, nullptr);
if (robot.isConnected()){
cout << "Kobuki reconnected successfully!" << endl;
kobuki_connected = true;
}
else{
cout << "Failed to reconnect Kobuki, retrying in 5 seconds..." << endl;
}
}
// Wacht voordat je opnieuw controleert
std::this_thread::sleep_for(std::chrono::seconds(5));
}
}
std::string readMQTT() std::string readMQTT()
{ {
static std::string lastMessage; static std::string lastMessage;

View File

@@ -48,7 +48,6 @@ def on_message(client, userdata, message):
x1, y1, x2, y2 = map(int, box.xyxy[0]) x1, y1, x2, y2 = map(int, box.xyxy[0])
cv2.rectangle(processed_image, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.rectangle(processed_image, (x1, y1), (x2, y2), (0, 255, 0), 2)
cv2.putText(processed_image, f"{class_name} {box.conf.item():.2f}", (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 0), 2) cv2.putText(processed_image, f"{class_name} {box.conf.item():.2f}", (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 0), 2)
# yolo_results_db()
# Create an MQTT client instance # Create an MQTT client instance
mqtt_client = mqtt.Client() mqtt_client = mqtt.Client()
@@ -86,6 +85,7 @@ def index():
@app.route('/control', methods=["GET", "POST"]) @app.route('/control', methods=["GET", "POST"])
def control(): def control():
if request.authorization and request.authorization.username == 'ishak' and request.authorization.password == 'kobuki': if request.authorization and request.authorization.username == 'ishak' and request.authorization.password == 'kobuki':
yolo_results_db()
return render_template('control.html') return render_template('control.html')
else: else:
return ('Unauthorized', 401, {'WWW-Authenticate': 'Basic realm="Login Required"'}) return ('Unauthorized', 401, {'WWW-Authenticate': 'Basic realm="Login Required"'})
@@ -161,30 +161,25 @@ def image():
@app.route('/yolo_results', methods=['GET']) @app.route('/yolo_results', methods=['GET'])
def yolo_results_endpoint(): def yolo_results_endpoint():
global yolo_results global yolo_results
return jsonify(yolo_results)
def yolo_results_db():
global yolo_results
with lock: with lock:
print(f"YOLO Results: {yolo_results}") # Debug statement try:
db = get_db() db = get_db()
with db.cursor() as cursor: with db.cursor() as cursor:
sql_yolo = "INSERT INTO image (class, confidence) VALUES (%s, %s)" sql_yolo = "INSERT INTO image (class, confidence) VALUES (%s, %s)"
yolo_tuples = [(result["class"], result["confidence"]) for result in yolo_results] yolo_tuples = [(result["class"], result["confidence"]) for result in yolo_results]
print(f"YOLO Tuples: {yolo_tuples}") # Debug statement print(f"YOLO Tuples: {yolo_tuples}") # Debug statement
cursor.executemany(sql_yolo, yolo_tuples) cursor.executemany(sql_yolo, yolo_tuples)
db.commit() db.commit()
cursor.close() cursor.close()
return jsonify(yolo_results) except mysql.connector.Error as err:
print(f"Database error: {err}")
# def yolo_results_db(): except Exception as e:
# global yolo_results print(f"Unexpected error: {e}")
# with lock:
# db = get_db()
# with db.cursor() as cursor:
# sql_yolo = "INSERT INTO image (object, confidence) VALUES (%s, %s)"
# yolo_tuples = [(result["class"], result["confidence"]) for result in yolo_results]
# cursor.executemany(sql_yolo, yolo_tuples)
# db.commit()
# cursor.close()
if __name__ == '__main__': if __name__ == '__main__':
app.run(debug=True, port=5000) app.run(debug=True, port=5000)