From 55826ea7592053ed3799895f8f9ff3e74fb4b9df Mon Sep 17 00:00:00 2001 From: Sam Hos Date: Wed, 18 Sep 2024 16:41:44 +0200 Subject: [PATCH 01/24] Added driver and fixed it --- src/C++/Driver/.gitignore | 33 ++ src/C++/Driver/CMakeLists.txt | 13 + src/C++/Driver/LICENSE | 21 + src/C++/Driver/Makefile | 208 ++++++++ src/C++/Driver/cmake_install.cmake | 62 +++ src/C++/Driver/src/CKobuki.cpp | 740 +++++++++++++++++++++++++++++ src/C++/Driver/src/CKobuki.h | 224 +++++++++ src/C++/Driver/src/graph.h | 71 +++ src/C++/Driver/src/main.cpp | 22 + src/C++/main.cpp | 12 +- src/C++/main.o | Bin 4336 -> 32680 bytes src/C++/progr | Bin 17016 -> 25888 bytes 12 files changed, 1405 insertions(+), 1 deletion(-) create mode 100644 src/C++/Driver/.gitignore create mode 100644 src/C++/Driver/CMakeLists.txt create mode 100644 src/C++/Driver/LICENSE create mode 100644 src/C++/Driver/Makefile create mode 100644 src/C++/Driver/cmake_install.cmake create mode 100755 src/C++/Driver/src/CKobuki.cpp create mode 100755 src/C++/Driver/src/CKobuki.h create mode 100644 src/C++/Driver/src/graph.h create mode 100644 src/C++/Driver/src/main.cpp diff --git a/src/C++/Driver/.gitignore b/src/C++/Driver/.gitignore new file mode 100644 index 0000000..1d23b8b --- /dev/null +++ b/src/C++/Driver/.gitignore @@ -0,0 +1,33 @@ +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod +*.smod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app + +CMakeFiles/* +build/obj/* + diff --git a/src/C++/Driver/CMakeLists.txt b/src/C++/Driver/CMakeLists.txt new file mode 100644 index 0000000..9c66fba --- /dev/null +++ b/src/C++/Driver/CMakeLists.txt @@ -0,0 +1,13 @@ +cmake_minimum_required(VERSION 3.9) +project(kobuki_control) + +#set(CMAKE_CXX_STANDARD 11) +find_package( OpenCV REQUIRED ) + +set(SOURCE_FILES + src/CKobuki.cpp + src/CKobuki.h + src/main.cpp) + +add_executable(kobuki_control ${SOURCE_FILES}) +#target_link_libraries(kobuki_control ) \ No newline at end of file diff --git a/src/C++/Driver/LICENSE b/src/C++/Driver/LICENSE new file mode 100644 index 0000000..4d91c5a --- /dev/null +++ b/src/C++/Driver/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2016 National Centre of Robotics + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/src/C++/Driver/Makefile b/src/C++/Driver/Makefile new file mode 100644 index 0000000..ea53047 --- /dev/null +++ b/src/C++/Driver/Makefile @@ -0,0 +1,208 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 3.30 + +# Default target executed when no arguments are given to make. +default_target: all +.PHONY : default_target + +# Allow only one "make -f Makefile2" at a time, but pass parallelism. +.NOTPARALLEL: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/sam/Desktop/rooziinuubii79/src/C++/Driver + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/sam/Desktop/rooziinuubii79/src/C++/Driver + +#============================================================================= +# Targets provided globally by CMake. + +# Special rule for the target edit_cache +edit_cache: + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --cyan "Running CMake cache editor..." + /usr/bin/ccmake -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) +.PHONY : edit_cache + +# Special rule for the target edit_cache +edit_cache/fast: edit_cache +.PHONY : edit_cache/fast + +# Special rule for the target rebuild_cache +rebuild_cache: + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --cyan "Running CMake to regenerate build system..." + /usr/bin/cmake --regenerate-during-build -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) +.PHONY : rebuild_cache + +# Special rule for the target rebuild_cache +rebuild_cache/fast: rebuild_cache +.PHONY : rebuild_cache/fast + +# The main all target +all: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/sam/Desktop/rooziinuubii79/src/C++/Driver/CMakeFiles /home/sam/Desktop/rooziinuubii79/src/C++/Driver//CMakeFiles/progress.marks + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 all + $(CMAKE_COMMAND) -E cmake_progress_start /home/sam/Desktop/rooziinuubii79/src/C++/Driver/CMakeFiles 0 +.PHONY : all + +# The main clean target +clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 clean +.PHONY : clean + +# The main clean target +clean/fast: clean +.PHONY : clean/fast + +# Prepare targets for installation. +preinstall: all + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 preinstall +.PHONY : preinstall + +# Prepare targets for installation. +preinstall/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 preinstall +.PHONY : preinstall/fast + +# clear depends +depend: + $(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 1 +.PHONY : depend + +#============================================================================= +# Target rules for targets named kobuki_control + +# Build rule for target. +kobuki_control: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 kobuki_control +.PHONY : kobuki_control + +# fast build rule for target. +kobuki_control/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/kobuki_control.dir/build.make CMakeFiles/kobuki_control.dir/build +.PHONY : kobuki_control/fast + +src/CKobuki.o: src/CKobuki.cpp.o +.PHONY : src/CKobuki.o + +# target to build an object file +src/CKobuki.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/kobuki_control.dir/build.make CMakeFiles/kobuki_control.dir/src/CKobuki.cpp.o +.PHONY : src/CKobuki.cpp.o + +src/CKobuki.i: src/CKobuki.cpp.i +.PHONY : src/CKobuki.i + +# target to preprocess a source file +src/CKobuki.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/kobuki_control.dir/build.make CMakeFiles/kobuki_control.dir/src/CKobuki.cpp.i +.PHONY : src/CKobuki.cpp.i + +src/CKobuki.s: src/CKobuki.cpp.s +.PHONY : src/CKobuki.s + +# target to generate assembly for a file +src/CKobuki.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/kobuki_control.dir/build.make CMakeFiles/kobuki_control.dir/src/CKobuki.cpp.s +.PHONY : src/CKobuki.cpp.s + +src/main.o: src/main.cpp.o +.PHONY : src/main.o + +# target to build an object file +src/main.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/kobuki_control.dir/build.make CMakeFiles/kobuki_control.dir/src/main.cpp.o +.PHONY : src/main.cpp.o + +src/main.i: src/main.cpp.i +.PHONY : src/main.i + +# target to preprocess a source file +src/main.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/kobuki_control.dir/build.make CMakeFiles/kobuki_control.dir/src/main.cpp.i +.PHONY : src/main.cpp.i + +src/main.s: src/main.cpp.s +.PHONY : src/main.s + +# target to generate assembly for a file +src/main.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/kobuki_control.dir/build.make CMakeFiles/kobuki_control.dir/src/main.cpp.s +.PHONY : src/main.cpp.s + +# Help Target +help: + @echo "The following are some of the valid targets for this Makefile:" + @echo "... all (the default if no target is provided)" + @echo "... clean" + @echo "... depend" + @echo "... edit_cache" + @echo "... rebuild_cache" + @echo "... kobuki_control" + @echo "... src/CKobuki.o" + @echo "... src/CKobuki.i" + @echo "... src/CKobuki.s" + @echo "... src/main.o" + @echo "... src/main.i" + @echo "... src/main.s" +.PHONY : help + + + +#============================================================================= +# Special targets to cleanup operation of make. + +# Special rule to run CMake to check the build system integrity. +# No rule that depends on this can have commands that come from listfiles +# because they might be regenerated. +cmake_check_build_system: + $(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 0 +.PHONY : cmake_check_build_system + diff --git a/src/C++/Driver/cmake_install.cmake b/src/C++/Driver/cmake_install.cmake new file mode 100644 index 0000000..45179d9 --- /dev/null +++ b/src/C++/Driver/cmake_install.cmake @@ -0,0 +1,62 @@ +# Install script for directory: /home/sam/Desktop/rooziinuubii79/src/C++/Driver + +# Set the install prefix +if(NOT DEFINED CMAKE_INSTALL_PREFIX) + set(CMAKE_INSTALL_PREFIX "/usr/local") +endif() +string(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}") + +# Set the install configuration name. +if(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME) + if(BUILD_TYPE) + string(REGEX REPLACE "^[^A-Za-z0-9_]+" "" + CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}") + else() + set(CMAKE_INSTALL_CONFIG_NAME "") + endif() + message(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"") +endif() + +# Set the component getting installed. +if(NOT CMAKE_INSTALL_COMPONENT) + if(COMPONENT) + message(STATUS "Install component: \"${COMPONENT}\"") + set(CMAKE_INSTALL_COMPONENT "${COMPONENT}") + else() + set(CMAKE_INSTALL_COMPONENT) + endif() +endif() + +# Install shared libraries without execute permission? +if(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE) + set(CMAKE_INSTALL_SO_NO_EXE "0") +endif() + +# Is this installation the result of a crosscompile? +if(NOT DEFINED CMAKE_CROSSCOMPILING) + set(CMAKE_CROSSCOMPILING "FALSE") +endif() + +# Set path to fallback-tool for dependency-resolution. +if(NOT DEFINED CMAKE_OBJDUMP) + set(CMAKE_OBJDUMP "/usr/bin/objdump") +endif() + +if(CMAKE_INSTALL_COMPONENT) + if(CMAKE_INSTALL_COMPONENT MATCHES "^[a-zA-Z0-9_.+-]+$") + set(CMAKE_INSTALL_MANIFEST "install_manifest_${CMAKE_INSTALL_COMPONENT}.txt") + else() + string(MD5 CMAKE_INST_COMP_HASH "${CMAKE_INSTALL_COMPONENT}") + set(CMAKE_INSTALL_MANIFEST "install_manifest_${CMAKE_INST_COMP_HASH}.txt") + unset(CMAKE_INST_COMP_HASH) + endif() +else() + set(CMAKE_INSTALL_MANIFEST "install_manifest.txt") +endif() + +if(NOT CMAKE_INSTALL_LOCAL_ONLY) + string(REPLACE ";" "\n" CMAKE_INSTALL_MANIFEST_CONTENT + "${CMAKE_INSTALL_MANIFEST_FILES}") + file(WRITE "/home/sam/Desktop/rooziinuubii79/src/C++/Driver/${CMAKE_INSTALL_MANIFEST}" + "${CMAKE_INSTALL_MANIFEST_CONTENT}") +endif() diff --git a/src/C++/Driver/src/CKobuki.cpp b/src/C++/Driver/src/CKobuki.cpp new file mode 100755 index 0000000..8010067 --- /dev/null +++ b/src/C++/Driver/src/CKobuki.cpp @@ -0,0 +1,740 @@ +#include "CKobuki.h" +#include "termios.h" +#include "errno.h" +#include +#include + +plot p; +static std::vector vectorX; +static std::vector vectorY; +static std::vector vectorGyroTheta; + +// obsluha tty pod unixom +int set_interface_attribs2 (int fd, int speed, int parity) +{ + struct termios tty; + memset (&tty, 0, sizeof tty); + if (tcgetattr (fd, &tty) != 0) + { + printf ("error %d from tcgetattr", errno); + return -1; + } + + cfsetospeed (&tty, speed); + cfsetispeed (&tty, speed); + + tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; // 8-bit chars + // disable IGNBRK for mismatched speed tests; otherwise receive break + // as \000 chars + //tty.c_iflag &= ~IGNBRK; // disable break processing + tty.c_lflag = 0; // no signaling chars, no echo, + // no canonical processing + tty.c_oflag = 0; // no remapping, no delays + tty.c_cc[VMIN] = 0; // read doesn't block + tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout + + tty.c_iflag &= ~(IGNBRK | INLCR | ICRNL | IXON | IXOFF | IXANY); // shut off xon/xoff ctrl + + tty.c_cflag |= (CLOCAL | CREAD);// ignore modem controls, + // enable reading + tty.c_cflag &= ~(PARENB | PARODD); // shut off parity + tty.c_cflag |= parity; + tty.c_cflag &= ~CSTOPB; + tty.c_cflag &= ~CRTSCTS; + + if (tcsetattr (fd, TCSANOW, &tty) != 0) + { + printf ("error %d from tcsetattr", errno); + return -1; + } + return 0; +} + +void set_blocking2 (int fd, int should_block) +{ + struct termios tty; + memset (&tty, 0, sizeof tty); + if (tcgetattr (fd, &tty) != 0) + { + printf ("error %d from tggetattr", errno); + return; + } + + tty.c_cc[VMIN] = should_block ? 1 : 0; + tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout + + if (tcsetattr (fd, TCSANOW, &tty) != 0) + printf ("error %d setting term attributes", errno); +} + + + + + + +int CKobuki::connect(char * comportT) +{ + HCom= open(comportT,O_RDWR|O_NOCTTY|O_NONBLOCK); + + if ( HCom== -1 ) + { + printf("Kobuki nepripojeny\n"); + return HCom; + + } + else + { + set_interface_attribs2 (HCom, B115200, 0); // set speed to 115,200 bps, 8n1 (no parity) + set_blocking2 (HCom, 0); // set no blocking + /* struct termios settings; + tcgetattr(HCom, &settings); + + cfsetospeed(&settings, B115200); // baud rate + settings.c_cflag &= ~PARENB; // no parity + settings.c_cflag &= ~CSTOPB; // 1 stop bit + settings.c_cflag &= ~CSIZE; + settings.c_cflag |= CS8 | CLOCAL; // 8 bits + settings.c_lflag &= ~ICANON; // canonical mode + settings.c_cc[VTIME]=1; + settings.c_oflag &= ~OPOST; // raw output + + tcsetattr(HCom, TCSANOW, &settings); // apply the settings*/ + tcflush(HCom, TCOFLUSH); + + + printf("Kobuki pripojeny\n"); + return HCom; + } +} + +unsigned char * CKobuki::readKobukiMessage() +{ + unsigned char buffer[1]; + ssize_t Pocet; + buffer[0] = 0; + unsigned char * null_buffer(0); + //citame kym nezachytime zaciatok spravy + do { + Pocet=read(HCom,buffer,1); + } while (buffer[0] != 0xAA); + //mame zaciatok spravy (asi) + if (Pocet == 1 && buffer[0] == 0xAA) + { + //citame dalsi byte + do { + + Pocet=read(HCom,buffer,1); + + } while (Pocet != 1); // na linuxe -1 na windowse 0 + + + + //a ak je to druhy byte hlavicky + if (Pocet == 1 && buffer[0] == 0x55) + { + // precitame dlzku + Pocet=read(HCom,buffer,1); + + // ReadFile(hCom, buffer, 1, &Pocet, NULL); + if (Pocet == 1) + { + //mame dlzku.. nastavime vektor a precitame ho cely + int readLenght = buffer[0]; + unsigned char *outputBuffer = (unsigned char*)calloc(readLenght+4,sizeof(char)); + outputBuffer[0] = buffer[0]; + int pct = 0; + + do + { + Pocet = 0; + int readpoc = (readLenght+1 - pct); + Pocet=read(HCom,outputBuffer+1+pct,readpoc); + + pct = pct + (Pocet == -1 ? 0 : Pocet); + } while (pct != (readLenght+1 )); + + // tu si mozeme ceknut co chodi zo serial intefejsu Kobukiho + // for(int i=0;i>8,0x00,0x00, 0x00 }; + message[13] = message[2] ^ message[3] ^ message[4] ^ message[5] ^ message[6] ^ message[7] ^ message[8] ^ message[9] ^ message[10] ^ message[11] ^ message[12]; + + uint32_t pocet; + pocet=write(HCom,&message,14); + +} + +void CKobuki::setRotationSpeed(double radpersec) +{ + int speedvalue = radpersec * 230.0f / 2.0f; + unsigned char message[14] = { 0xaa,0x55,0x0A,0x0c,0x02,0xf0,0x00,0x01,0x04,speedvalue % 256,speedvalue >>8,0x01,0x00, 0x00 }; + message[13] = message[2] ^ message[3] ^ message[4] ^ message[5] ^ message[6] ^ message[7] ^ message[8] ^ message[9] ^ message[10] ^ message[11] ^ message[12]; + + uint32_t pocet; + pocet=write(HCom,&message,14); +} + +void CKobuki::setArcSpeed(int mmpersec, int radius) +{ + if (radius == 0) { + setTranslationSpeed(mmpersec); + return; + } + + int speedvalue = mmpersec * ((radius + (radius>0? 230:-230) )/ 2 ) / radius; + unsigned char message[14] = { 0xaa,0x55,0x0A,0x0c,0x02,0xf0,0x00,0x01,0x04,speedvalue % 256,speedvalue >>8,radius % 256,radius >>8, 0x00 }; + message[13] = message[2] ^ message[3] ^ message[4] ^ message[5] ^ message[6] ^ message[7] ^ message[8] ^ message[9] ^ message[10] ^ message[11] ^ message[12]; + uint32_t pocet; + pocet=write(HCom,&message,14); +} + +void CKobuki::setSound(int noteinHz, int duration) +{ + int notevalue = floor((double)1.0 / ((double)noteinHz*0.00000275) + 0.5); + unsigned char message[9] = { 0xaa,0x55,0x05,0x03,0x03,notevalue%256,notevalue>>8,duration%256,0x00 }; + message[8] = message[2] ^ message[3] ^ message[4] ^ message[5] ^ message[6] ^ message[7]; + + uint32_t pocet; + pocet=write(HCom,&message,9); +} + + + + +void CKobuki::startCommunication(char * portname, bool CommandsEnabled, void *userDataL) +{ + connect(portname); + enableCommands(CommandsEnabled); + userData = userDataL; + + int pthread_result; + pthread_result = pthread_create(&threadHandle,NULL,KobukiProcess,(void *)this); +} + + + + + +int CKobuki::measure() +{ + while (stopVlakno==0) + { + unsigned char *message = readKobukiMessage(); + if (message == NULL) + { + printf("vratil null message\n"); + continue; + } + int ok=parseKobukiMessage(data,message); + + //maximalne moze trvat callback funkcia 20 ms, ak by trvala viac, nestihame citat + if (ok == 0) + { + loop(userData, data); + } + free(message); + } + return 0; +} + +int CKobuki::parseKobukiMessage(TKobukiData &output, unsigned char * data) +{ + int rtrnvalue = checkChecksum(data); + //ak je zly checksum,tak kaslat na to + if (rtrnvalue != 0) + return -2; + + int checkedValue = 1; + //kym neprejdeme celu dlzku + while (checkedValue < data[0]) + { + //basic data subload + if (data[checkedValue] == 0x01) + { + checkedValue++; + if (data[checkedValue ] != 0x0F) + return -1; + checkedValue++; + output.timestamp = data[checkedValue + 1] * 256 + data[checkedValue]; + checkedValue += 2; + output.BumperCenter = data[checkedValue ] && 0x02; + output.BumperLeft = data[checkedValue] && 0x04; + output.BumperRight = data[checkedValue] && 0x01; + checkedValue++; + output.WheelDropLeft= data[checkedValue] && 0x02; + output.WheelDropRight = data[checkedValue] && 0x01; + checkedValue++; + output.CliffCenter = data[checkedValue] && 0x02; + output.CliffLeft = data[checkedValue] && 0x04; + output.CliffRight = data[checkedValue] && 0x01; + checkedValue++; + output.EncoderLeft = data[checkedValue + 1] * 256 + data[checkedValue]; + checkedValue += 2; + output.EncoderRight = data[checkedValue + 1] * 256 + data[checkedValue]; + checkedValue += 2; + output.PWMleft = data[checkedValue] ; + checkedValue++; + output.PWMright = data[checkedValue] ; + checkedValue++; + output.ButtonPress = data[checkedValue]; + checkedValue++; + output.Charger = data[checkedValue]; + checkedValue++; + output.Battery = data[checkedValue]; + checkedValue++; + output.overCurrent = data[checkedValue]; + checkedValue++; + } + else if (data[checkedValue] == 0x03) + { + checkedValue++; + if (data[checkedValue] != 0x03) + return -3; + checkedValue++; + output.IRSensorRight = data[checkedValue]; + checkedValue++; + output.IRSensorCenter = data[checkedValue]; + checkedValue++; + output.IRSensorLeft = data[checkedValue]; + checkedValue++; + } + else if (data[checkedValue] == 0x04) + { + checkedValue++; + if (data[checkedValue] != 0x07) + return -4; + checkedValue++; + output.GyroAngle = data[checkedValue + 1] * 256 + data[checkedValue]; + checkedValue += 2; + output.GyroAngleRate = data[checkedValue + 1] * 256 + data[checkedValue]; + checkedValue += 5;//3 unsued + } + else if (data[checkedValue] == 0x05) + { + checkedValue++; + if (data[checkedValue] != 0x06) + return -5; + checkedValue++; + output.CliffSensorRight = data[checkedValue + 1] * 256 + data[checkedValue]; + checkedValue += 2; + output.CliffSensorCenter = data[checkedValue + 1] * 256 + data[checkedValue]; + checkedValue += 2; + output.CliffSensorLeft = data[checkedValue + 1] * 256 + data[checkedValue]; + checkedValue += 2; + } + else if (data[checkedValue] == 0x06) + { + checkedValue++; + if (data[checkedValue] != 0x02) + return -6; + checkedValue++; + output.wheelCurrentLeft = data[checkedValue]; + checkedValue ++; + output.wheelCurrentRight =data[checkedValue]; + checkedValue ++; + + } + else if (data[checkedValue] == 0x0A) + { + checkedValue++; + if (data[checkedValue] != 0x04) + return -7; + checkedValue++; + output.extraInfo.HardwareVersionPatch = data[checkedValue]; + checkedValue++; + output.extraInfo.HardwareVersionMinor = data[checkedValue]; + checkedValue++; + output.extraInfo.HardwareVersionMajor = data[checkedValue]; + checkedValue += 2; + + } + else if (data[checkedValue] == 0x0B) + { + checkedValue++; + if (data[checkedValue] != 0x04) + return -8; + checkedValue++; + output.extraInfo.FirmwareVersionPatch = data[checkedValue]; + checkedValue++; + output.extraInfo.FirmwareVersionMinor = data[checkedValue]; + checkedValue++; + output.extraInfo.FirmwareVersionMajor = data[checkedValue]; + checkedValue += 2; + + } + else if (data[checkedValue] == 0x0D) + { + checkedValue++; + if (data[checkedValue]%2 !=0) + return -9; + checkedValue++; + output.frameId = data[checkedValue]; + checkedValue++; + int howmanyFrames = data[checkedValue]/3; + checkedValue++; + output.gyroData.reserve(howmanyFrames); + output.gyroData.clear(); + for (int hk = 0; hk < howmanyFrames; hk++) + { + TRawGyroData temp; + temp.x = data[checkedValue + 1] * 256 + data[checkedValue]; + checkedValue += 2; + temp.y = data[checkedValue + 1] * 256 + data[checkedValue]; + checkedValue += 2; + temp.z = data[checkedValue + 1] * 256 + data[checkedValue]; + checkedValue += 2; + output.gyroData.push_back(temp); + } + } + else if (data[checkedValue] == 0x10) + { + checkedValue++; + if (data[checkedValue] != 0x10) + return -10; + checkedValue++; + output.digitalInput = data[checkedValue + 1] * 256 + data[checkedValue]; + checkedValue += 2; + output.analogInputCh0 = data[checkedValue + 1] * 256 + data[checkedValue]; + checkedValue += 2; + output.analogInputCh1 = data[checkedValue + 1] * 256 + data[checkedValue]; + checkedValue += 2; + output.analogInputCh2 = data[checkedValue + 1] * 256 + data[checkedValue]; + checkedValue += 2; + output.analogInputCh3 = data[checkedValue + 1] * 256 + data[checkedValue]; + checkedValue += 8;//2+6 + + + } + else if (data[checkedValue] == 0x13) + { + checkedValue++; + if (data[checkedValue] != 0x0C) + return -11; + checkedValue++; + output.extraInfo.UDID0 = data[checkedValue + 3] * 256*256*256+ data[checkedValue + 2] * 256*256+ data[checkedValue + 1] * 256 + data[checkedValue]; + checkedValue += 4; + output.extraInfo.UDID1 = data[checkedValue + 3] * 256 * 256 * 256 + data[checkedValue + 2] * 256 * 256 +data[checkedValue + 1] * 256 + data[checkedValue]; + checkedValue += 4; + output.extraInfo.UDID2 = data[checkedValue + 3] * 256 * 256 * 256 + data[checkedValue + 2] * 256 * 256 +data[checkedValue + 1] * 256 + data[checkedValue]; + checkedValue += 4; + } + else + { + checkedValue++; + checkedValue += data[checkedValue] + 1; + } + } + return 0; +} + + + + + + + +long double CKobuki::gyroToRad(signed short GyroAngle) { + + long double ret; + if (GyroAngle < 0) { + ret = GyroAngle + 36000; + } + else { + ret = GyroAngle; + } + return (long double) ret*PI/18000.0; +} + + + + + +long CKobuki::loop(void *user_data, TKobukiData &Kobuki_data) { + if (iterationCount == 0) { + prevLeftEncoder = Kobuki_data.EncoderLeft; + prevRightEncoder = Kobuki_data.EncoderRight; + prevTimestamp = Kobuki_data.timestamp; + prevGyroTheta = gyroToRad(Kobuki_data.GyroAngle); + iterationCount++; + } + + int dLeft; + if (abs(Kobuki_data.EncoderLeft - prevLeftEncoder) > 32000) { + dLeft = Kobuki_data.EncoderLeft - prevLeftEncoder + (Kobuki_data.EncoderLeft > prevLeftEncoder ? -65536 : +65536); + } + else { + dLeft = Kobuki_data.EncoderLeft - prevLeftEncoder; + } + + int dRight; + if (abs(Kobuki_data.EncoderRight - prevRightEncoder) > 32000) { + dRight = Kobuki_data.EncoderRight - prevRightEncoder + (Kobuki_data.EncoderRight > prevRightEncoder ? -65536 : +65536); + } + else { + dRight = Kobuki_data.EncoderRight - prevRightEncoder; + } + + long double dGyroTheta = prevGyroTheta - gyroToRad(Kobuki_data.GyroAngle); + + if (dGyroTheta > PI) { + dGyroTheta -= 2*PI; + } + if (dGyroTheta < -1*PI) { + dGyroTheta += 2*PI; + } + + gyroTheta += dGyroTheta; + + uint16_t dTimestamp = Kobuki_data.timestamp - prevTimestamp; + + long double mLeft = dLeft*tickToMeter; + long double mRight = dRight*tickToMeter; + + if (mLeft == mRight) { + x = x + mRight; + } else { + x = x + (b*(mRight+mLeft))/(2*(mRight-mLeft))*(sin((mRight-mLeft)/b + theta) - sin(theta)); + y = y + (b*(mRight+mLeft))/(2*(mRight-mLeft))*(cos((mRight-mLeft)/b + theta) - cos(theta)); + theta = (mRight-mLeft)/b + theta; + } + + displacement = (mRight + mLeft)/2; + integratedGyroTheta = integratedGyroTheta + dGyroTheta; + gx = gx + displacement * cos(integratedGyroTheta + dGyroTheta / 2); + + gy = gy + displacement * sin(integratedGyroTheta + dGyroTheta / 2); + + + + + + + totalLeft +=dLeft; + totalRight +=dRight; + + // ak je suma novej a predchadzajucej vacsia ako 65536 tak to pretieklo? + directionL = (prevLeftEncoder < Kobuki_data.EncoderLeft ? 1 : -1); + directionR = (prevRightEncoder < Kobuki_data.EncoderRight ? 1 : -1); + dTimestamp = (Kobuki_data.timestamp < prevTimestamp ? prevTimestamp - Kobuki_data.timestamp + 65536 : dTimestamp); + + + prevLeftEncoder = Kobuki_data.EncoderLeft; + prevRightEncoder = Kobuki_data.EncoderRight; + prevTimestamp = Kobuki_data.timestamp; + prevGyroTheta = gyroToRad(Kobuki_data.GyroAngle); + + +// std::cout << "X: " << x +// << " Y: " << y +// << " Theta: " << theta +// << "Gyro theta:" << gyroTheta +// << std::endl; + + + static long counter = 0; + + vectorX.push_back(gx); + vectorY.push_back(gy); + vectorGyroTheta.push_back(gyroTheta); + + if (counter % 100 == 0) { + p.plot_data(vectorY, vectorX); + } + counter++; + + return 0; +} + + + + +// povie kobukimu ze ma ist niekolko metrov dopredu alebo dozadu, rozhoduje znamienko +// funkcia kompenzuje chodenie rovno pomocou regulatora, interne vyuziva setArcSpeed a +// ako spatnu vazbu pouziva data z enkoderov +void CKobuki::goStraight(long double distance){ + long double u_translation = 0; // riadena velicina, rychlost robota pri pohybe + long double w_translation = distance; // pozadovana hodnota + + // parametre regulatora + long double Kp_translation = 4500; + long double e_translation = 0; + int upper_thresh_translation = 600; + int lower_thresh_translation = 40; + int translation_start_gain = 20; + + long double u_rotation = 0; // riadena velicina + long double w_rotation = 0; + long double Kp_rotation = 57; + long double e_rotation = 0; + + x = 0; + y = 0; + theta = 0; + + long i = 5; + + while (fabs(x - w_translation) > 0.005 && x upper_thresh_translation) + u_translation = upper_thresh_translation; + if (u_translation < lower_thresh_translation) + u_translation = lower_thresh_translation; + + // rewrite starting speed with line + if (i < u_translation) { + u_translation = i; + } + + if (fabs(u_rotation) > 32767) { + u_rotation = -32767; + } + + if (u_rotation == 0) { + u_rotation = -32767; + } + + this->setArcSpeed(u_translation, u_rotation); + + usleep(25*1000); + // increment starting speed + i = i + translation_start_gain; + } + this->setTranslationSpeed(0); +} + + + +/// metoda vykona rotaciu, rotuje sa pomocou regulatora, ako spatna vazba sluzi gyroskop, +/// kedze je radovo presnejsi ako enkodery +void CKobuki::doRotation(long double th) { + long double u = 0; // riadena velicina, uhlova rychlost robota pri pohybe + long double w = th; // pozadovana hodnota v radianoch + long double Kp = PI; + long double e = 0; + int thresh = PI/2; + + theta = 0; + x = 0; + y = 0; + gyroTheta = 0; + + long double i = 0; + + if (w > 0) { + while (gyroTheta < w) { + e = w - gyroTheta; + u = Kp*e; + + if (u > thresh) u = thresh; + if (u < 0.4) u = 0.4; + + if (i < u) { + u = i; + } + + std::cout << "Angle: " << gyroTheta << " required:" << w << std::endl; + this->setRotationSpeed(-1*u); + usleep(25*1000); + i = i + 0.1; + } + } + else { + while (gyroTheta > w) { + e = w - gyroTheta; + u = Kp*e*-1; + + if (u > thresh) u = thresh; + if (u < 0.4) u = 0.4; + + if (i < u) { + u = i; + } + + std::cout << "Angle: " << gyroTheta << " required:" << w << std::endl; + this->setRotationSpeed(u); + usleep(25*1000); + i = i + 0.1; + } + } + + std::cout << "stop the fuck!" << std::endl; + // usleep(25*1000); + this->setRotationSpeed(0); + usleep(25*1000); +} + + +// kombinuje navadzanie na suradnicu a rotaciu o uhol, realizuje presun na zvolenu suradnicu +// v suradnicovom systeme robota +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; +} + diff --git a/src/C++/Driver/src/CKobuki.h b/src/C++/Driver/src/CKobuki.h new file mode 100755 index 0000000..05a19fd --- /dev/null +++ b/src/C++/Driver/src/CKobuki.h @@ -0,0 +1,224 @@ +//#pragma once +////************************************************************************************* +////************************************************************************************* +//// autor Martin Dekan a Peter Beno mail: dekdekan@gmail.com, peter.beno@stuba.sk +////------------------------------------------------------------------------------------- +//// co to je: +//// trieda na pracu s robotom kobuki. mala by mat implementovane citanie dat +//// a posielanie prikazov... +//// neobsahuje ziadnu logiku co s datami robit, to je na userovi aby spravil v callback funkcii +// jedna sa vlastne len o implementaciu komunikacie s hardwareom, driver +////************************************************************************************* +////************************************************************************************* +#ifndef KOBUKI_CLASS_123456789 +#define KOBUKI_CLASS_123456789 +#define PI 3.141592653589793238462643383279502884L /* pi */ +#define MS_INSTRUCTION_DELAY 25 + +#include +#include +#include +#include "pthread.h" +#include "unistd.h" +#include "fcntl.h" +#include "string.h" +#include +#include +#include +#include +#include +#include +#include +#include + +#include "graph.h" + +using namespace std; + +typedef struct +{ + + unsigned short x; + unsigned short y; + unsigned short z; + +}TRawGyroData; +typedef struct +{ + //Hardware Version + unsigned char HardwareVersionMajor; + unsigned char HardwareVersionMinor; + unsigned char HardwareVersionPatch; + //Firmware Version + unsigned char FirmwareVersionMajor; + unsigned char FirmwareVersionMinor; + unsigned char FirmwareVersionPatch; + + //Unique Device IDentifier(UDID) + unsigned int UDID0; + unsigned int UDID1; + unsigned int UDID2; + //Controller Info + unsigned char PIDtype; + unsigned int PIDgainP; + unsigned int PIDgainI; + unsigned int PIDgainD; +}TExtraRequestData; + +typedef struct +{ + //---zakladny balik + unsigned short timestamp; + //narazniky + bool BumperLeft; + bool BumperCenter; + bool BumperRight; + //cliff + bool CliffLeft; + bool CliffCenter; + bool CliffRight; + // padnutie kolies + bool WheelDropLeft; + bool WheelDropRight; + //tocenie kolies + unsigned short EncoderRight; + unsigned short EncoderLeft; + unsigned char PWMright; + unsigned char PWMleft; + //gombiky + unsigned char ButtonPress;// 0 nie, 1 2 4 pre button 0 1 2 (7 je ze vsetky tri) + //napajanie + unsigned char Charger; + unsigned char Battery; + unsigned char overCurrent; + //---docking ir + unsigned char IRSensorRight; + unsigned char IRSensorCenter; + unsigned char IRSensorLeft; + //---Inertial Sensor Data + signed short GyroAngle; + unsigned short GyroAngleRate; + //---Cliff Sensor Data + unsigned short CliffSensorRight; + unsigned short CliffSensorCenter; + unsigned short CliffSensorLeft; + //---Current + unsigned char wheelCurrentLeft; + unsigned char wheelCurrentRight; + //---Raw Data Of 3D Gyro + unsigned char frameId; + std::vector gyroData; + //---General Purpose Input + unsigned short digitalInput; + unsigned short analogInputCh0; + unsigned short analogInputCh1; + unsigned short analogInputCh2; + unsigned short analogInputCh3; + //---struktura s datami ktore sa nam tam objavia iba na poziadanie + TExtraRequestData extraInfo; +}TKobukiData; + + +typedef long(*src_callback_kobuki_data) (void *user_data, TKobukiData &Kobuki_data); + +class CKobuki +{ +public: + CKobuki() { + stopVlakno = 0; + std::cout << "kobuki instantiated" << std::endl; + odometry_log.open("odometry.txt"); + }; + virtual ~CKobuki() { + stopVlakno = 1; + close(HCom); + pthread_cancel(threadHandle); + odometry_log.close(); + }; + + void enableCommands(bool commands) { + enabledCommands = commands; + }; + + + long loop(void *user_data, TKobukiData &Kobuki_data); + + void startCommunication(char *portname,bool CommandsEnabled,void *userDataL); + int measure(); //vlaknova funkcia, ma v sebe nekonecne vlakno a vycitava udaje + void setLed(int led1 = 0, int led2 = 0); //led1 zelena/cervena 2/1, //led2 zelena/cervena 2/1 + void setTranslationSpeed(int mmpersec); + void setRotationSpeed(double radpersec); + void setArcSpeed(int mmpersec,int radius); + void setSound(int noteinHz, int duration); + void setPower(int value); + + // control functions + void goStraight(long double distance); + void doRotation(long double th); + void goToXy(long double xx, long double yy); + std::ofstream odometry_log; + + + + +private: + int HCom; + pthread_t threadHandle; // handle na vlakno + int threadID; // id vlakna + int stopVlakno; + TKobukiData data; + src_callback_kobuki_data callbackFunction; + void *userData; + bool enabledCommands; + int parseKobukiMessage(TKobukiData &output, unsigned char *data ); + int connect(char *portname); + unsigned char *readKobukiMessage(); + int checkChecksum(unsigned char *data); + + //--spustenie merania v novom vlakne (vycitavanie bezi v novom vlakne. treba ho stopnut ak chceme poslat request) + static void * KobukiProcess(void *param) + { + //std::cout << "Nase vlakno Kobuki process nastartovalo" << std::endl; + CKobuki *hoku = (CKobuki*)param; + int vystup = hoku->measure(); + + return param; + } + + + // internal variables for robot control + int prevLeftEncoder, prevRightEncoder; // [ticks] + uint16_t prevTimestamp;// [ms] + long totalLeft, totalRight = 0; + int directionL = 0; // 1 = forward, 0 = undefined, -1 = backwards + int directionR = 0; + int iterationCount = 0; + long double tickToMeter = 0.000085292090497737556558; // [m/tick] +// + long double x = 0; // [m] + long double y = 0; +// + long double theta = 0; // [rad] + long double b = 0.23; // wheelbase distance in meters, from kobuki manual https://yujinrobot.github.io/kobuki/doxygen/enAppendixProtocolSpecification.html +// + long double prevGyroTheta = 0; + long double gyroTheta = 0; // [rad] + + // utilities + long double gyroToRad(signed short GyroAngle); + + plot p; + std::vector vectorX; + std::vector vectorY; + std::vector vectorGyroTheta; + + + double displacement = 0; + double integratedGyroTheta = 0; + double gx = 0; + double gy = 0; + + +}; + +#endif diff --git a/src/C++/Driver/src/graph.h b/src/C++/Driver/src/graph.h new file mode 100644 index 0000000..89c963c --- /dev/null +++ b/src/C++/Driver/src/graph.h @@ -0,0 +1,71 @@ +#ifndef GRAPH1010 +#define GRAPH1010 +#include +#include +#include + +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 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,vector 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,y; + for(int k=a;k +#include + +#include "graph.h" + +using namespace std; + +int main() { + unsigned char * null_ptr(0); + CKobuki robot; + + robot.startCommunication("/dev/ttyUSB0", true, null_ptr); + usleep(1*1000*1000); + + robot.goStraight(10); + + + + + usleep(30*1000*1000); +} diff --git a/src/C++/main.cpp b/src/C++/main.cpp index 5065b0f..b78a180 100644 --- a/src/C++/main.cpp +++ b/src/C++/main.cpp @@ -1,9 +1,12 @@ //before running set right baudrate //sudo stty -F /dev/ttyUSB0 speed 115200 cs8 -cstopb -parenb +//TODO: Fix the first output of the buffer #include #include #include #include +#include + int main() { char byte; @@ -21,9 +24,16 @@ int main() { if (foundAA) { if (ubyte == 0b01010101) { // 0x55 std::cout << "Found 0xAA followed by 0x55" << std::endl; - std::cout << buffer.size() << std::endl; //display size of buffer + // std::cout << "Buffer size" << buffer.size() << std::endl << std::endl; + // Print the buffer in hex values + for (int i = 0; i < 4; i++) { + std::cout << "0x" << std::hex << std::setw(2) << std::setfill('0') << static_cast(static_cast(buffer[i])) << " "; + } + //reset buffer after new 0XAA and 0x55 is found buffer.clear(); foundAA = false; // Reset the state + if (ubyte == 0b10101010) + foundAA = true; } else { foundAA = false; // Reset the state if the next byte is not 0x55 } diff --git a/src/C++/main.o b/src/C++/main.o index fc7852753744c7f6ef8a80422b1395ae17ac85c6..d2cd5c527e8ea173fcc9ab99c9e0dc2446bc4004 100644 GIT binary patch literal 32680 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 JeKP6%{{u)n=*9p5 literal 4336 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 q77Zwe52%8XcMqCwf_bk(5$2Y literal 17016 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 From c3acea864a443bae0a1548aaef5dabf996106d88 Mon Sep 17 00:00:00 2001 From: Sam Hos Date: Wed, 18 Sep 2024 16:43:41 +0200 Subject: [PATCH 02/24] attempt to fix old driver --- src/C++/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/C++/main.cpp b/src/C++/main.cpp index b78a180..d9f9787 100644 --- a/src/C++/main.cpp +++ b/src/C++/main.cpp @@ -40,6 +40,7 @@ int main() { } else if (ubyte == 0b10101010) { // 0xAA foundAA = true; } + } @@ -49,7 +50,6 @@ int main() { - //Tomorrow //Try to use vectors and store every byte in its own array object by dividing the buffer into 8 bits From 13c29e9af82a0ea808d7525a7524cfe88fbfa79e Mon Sep 17 00:00:00 2001 From: Sam Hos Date: Mon, 23 Sep 2024 11:40:16 +0200 Subject: [PATCH 03/24] Update gitignore --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index eec1c31..f384d63 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,6 @@ src/C++/main.o src/C++/progr .vscode/settings.json +src/C++/Driver/odometry.txt +src/C++/Driver/CMakeCache.txt +src/C++/Driver/kobuki_control From 90057414a47c9124c0b5e28ebe857312615e964f Mon Sep 17 00:00:00 2001 From: Sam Hos Date: Mon, 23 Sep 2024 11:40:33 +0200 Subject: [PATCH 04/24] change data to public --- src/C++/Driver/src/CKobuki.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/C++/Driver/src/CKobuki.h b/src/C++/Driver/src/CKobuki.h index 05a19fd..6d326b5 100755 --- a/src/C++/Driver/src/CKobuki.h +++ b/src/C++/Driver/src/CKobuki.h @@ -157,6 +157,8 @@ public: void doRotation(long double th); void goToXy(long double xx, long double yy); std::ofstream odometry_log; + TKobukiData data; + @@ -166,7 +168,6 @@ private: pthread_t threadHandle; // handle na vlakno int threadID; // id vlakna int stopVlakno; - TKobukiData data; src_callback_kobuki_data callbackFunction; void *userData; bool enabledCommands; From bc0b6946f7b0b01bc7ea15cb2e397d1b76edcca3 Mon Sep 17 00:00:00 2001 From: Sam Hos Date: Mon, 23 Sep 2024 11:40:46 +0200 Subject: [PATCH 05/24] testing --- src/C++/Driver/src/CKobuki.cpp | 2 +- src/C++/Driver/src/main.cpp | 13 ++++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/C++/Driver/src/CKobuki.cpp b/src/C++/Driver/src/CKobuki.cpp index 8010067..9e78b91 100755 --- a/src/C++/Driver/src/CKobuki.cpp +++ b/src/C++/Driver/src/CKobuki.cpp @@ -263,7 +263,7 @@ int CKobuki::measure() unsigned char *message = readKobukiMessage(); if (message == NULL) { - printf("vratil null message\n"); + // printf("vratil null message\n"); continue; } int ok=parseKobukiMessage(data,message); diff --git a/src/C++/Driver/src/main.cpp b/src/C++/Driver/src/main.cpp index b36e98c..ad06838 100644 --- a/src/C++/Driver/src/main.cpp +++ b/src/C++/Driver/src/main.cpp @@ -5,18 +5,25 @@ #include "graph.h" using namespace std; +CKobuki robot; int main() { unsigned char * null_ptr(0); - CKobuki robot; robot.startCommunication("/dev/ttyUSB0", true, null_ptr); usleep(1*1000*1000); - robot.goStraight(10); - + robot.goStraight(1); + usleep(30*1000*1000); } + + +int checkCenterCliff() { + while(true) { + std::cout << "cliffsensordata:" << robot.data.CliffSensorCenter << std::endl; + } +} \ No newline at end of file From 0db8ab3e2ff7c75a0bb817ddc4cb25fd4f3497a9 Mon Sep 17 00:00:00 2001 From: Sam Hos Date: Mon, 23 Sep 2024 13:50:14 +0200 Subject: [PATCH 06/24] movement test --- src/C++/Driver/src/main.cpp | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/C++/Driver/src/main.cpp b/src/C++/Driver/src/main.cpp index ad06838..8ec94c6 100644 --- a/src/C++/Driver/src/main.cpp +++ b/src/C++/Driver/src/main.cpp @@ -9,19 +9,27 @@ CKobuki robot; int main() { unsigned char * null_ptr(0); - + int text; robot.startCommunication("/dev/ttyUSB0", true, null_ptr); usleep(1*1000*1000); - - robot.goStraight(1); - - - + cout << "Enter commando"; + cin >> text; + if (text == 1) { + robot.goStraight(10); + } + if (text == 2) { + robot.doRotation(90); + } + if (text == 3) { + robot.doRotation(90); + } + else { + cout << "no text specified"; + } usleep(30*1000*1000); } - int checkCenterCliff() { while(true) { std::cout << "cliffsensordata:" << robot.data.CliffSensorCenter << std::endl; From efa0692128908e46a20ad02a489ea40a3b41f84b Mon Sep 17 00:00:00 2001 From: Sam Hos Date: Mon, 23 Sep 2024 13:54:07 +0200 Subject: [PATCH 07/24] put movement in its own function --- src/C++/Driver/src/main.cpp | 64 +++++++++++++++++++++++-------------- 1 file changed, 40 insertions(+), 24 deletions(-) diff --git a/src/C++/Driver/src/main.cpp b/src/C++/Driver/src/main.cpp index 8ec94c6..029f252 100644 --- a/src/C++/Driver/src/main.cpp +++ b/src/C++/Driver/src/main.cpp @@ -1,37 +1,53 @@ #include "CKobuki.h" #include #include - +#include #include "graph.h" using namespace std; CKobuki robot; +int movement(); -int main() { - unsigned char * null_ptr(0); - int text; +int main() +{ + unsigned char *null_ptr(0); robot.startCommunication("/dev/ttyUSB0", true, null_ptr); - usleep(1*1000*1000); + usleep(1 * 1000 * 1000); cout << "Enter commando"; - cin >> text; - if (text == 1) { - robot.goStraight(10); - } - if (text == 2) { - robot.doRotation(90); - } - if (text == 3) { - robot.doRotation(90); - } - else { - cout << "no text specified"; - } - - usleep(30*1000*1000); + usleep(30 * 1000 * 1000); + thread mv(movement); } -int checkCenterCliff() { - while(true) { - std::cout << "cliffsensordata:" << robot.data.CliffSensorCenter << std::endl; +int checkCenterCliff() +{ + while (true) + { + std::cout << "cliffsensordata:" << robot.data.CliffSensorCenter << std::endl; } -} \ No newline at end of file +} + +int movement() +{ + int text; + while (true) + { + cin >> text; + + if (text == 1) + { + robot.goStraight(10); + } + if (text == 2) + { + robot.doRotation(90); + } + if (text == 3) + { + robot.doRotation(90); + } + else + { + cout << "no text specified"; + } + } +} From 3c58efa9a65aec8f43d1304a1cf65c1a6f01e24c Mon Sep 17 00:00:00 2001 From: Sam Hos Date: Mon, 23 Sep 2024 14:01:02 +0200 Subject: [PATCH 08/24] change values --- src/C++/Driver/src/main.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/C++/Driver/src/main.cpp b/src/C++/Driver/src/main.cpp index 029f252..28a0957 100644 --- a/src/C++/Driver/src/main.cpp +++ b/src/C++/Driver/src/main.cpp @@ -14,8 +14,8 @@ int main() robot.startCommunication("/dev/ttyUSB0", true, null_ptr); usleep(1 * 1000 * 1000); cout << "Enter commando"; - usleep(30 * 1000 * 1000); thread mv(movement); + usleep(30 * 1000 * 1000); } int checkCenterCliff() @@ -35,15 +35,15 @@ int movement() if (text == 1) { - robot.goStraight(10); + robot.goStraight(1); } if (text == 2) { - robot.doRotation(90); + robot.doRotation(0.25); } if (text == 3) { - robot.doRotation(90); + robot.doRotation(-0.25); } else { From 8221423a353734ff6bb7ec1d5637580a38d2a502 Mon Sep 17 00:00:00 2001 From: Sam Hos Date: Mon, 23 Sep 2024 14:14:37 +0200 Subject: [PATCH 09/24] testing bobot --- src/C++/Driver/src/main.cpp | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/C++/Driver/src/main.cpp b/src/C++/Driver/src/main.cpp index 28a0957..7feb324 100644 --- a/src/C++/Driver/src/main.cpp +++ b/src/C++/Driver/src/main.cpp @@ -37,17 +37,26 @@ int movement() { robot.goStraight(1); } - if (text == 2) + else if (text == 2) { + // 1 is full circle robot.doRotation(0.25); } - if (text == 3) + else if (text == 3) { - robot.doRotation(-0.25); + // Add your code here for text == 3 } else { - cout << "no text specified"; + try + { + robot.doRotation(text); + throw "NaN"; + } + catch (const char *msg) + { + cerr << msg << endl; + } } } -} +} \ No newline at end of file From c4ff439442e50eede1e5106e5fecd42429b17ed7 Mon Sep 17 00:00:00 2001 From: Sam Hos Date: Mon, 23 Sep 2024 14:23:15 +0200 Subject: [PATCH 10/24] translate comment --- src/C++/Driver/src/CKobuki.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/C++/Driver/src/CKobuki.cpp b/src/C++/Driver/src/CKobuki.cpp index 9e78b91..5cd090f 100755 --- a/src/C++/Driver/src/CKobuki.cpp +++ b/src/C++/Driver/src/CKobuki.cpp @@ -652,8 +652,8 @@ void CKobuki::goStraight(long double distance){ -/// metoda vykona rotaciu, rotuje sa pomocou regulatora, ako spatna vazba sluzi gyroskop, -/// kedze je radovo presnejsi ako enkodery +/// the method performs the rotation, it rotates using the regulator, the gyroscope serves as feedback, +/// because it is much more accurate than encoders void CKobuki::doRotation(long double th) { long double u = 0; // riadena velicina, uhlova rychlost robota pri pohybe long double w = th; // pozadovana hodnota v radianoch From f3970bf04f22e5adceb3d8a2239e07a964ee9fd5 Mon Sep 17 00:00:00 2001 From: Sam Hos Date: Mon, 23 Sep 2024 14:23:22 +0200 Subject: [PATCH 11/24] disable plotter --- src/C++/Driver/src/CKobuki.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/C++/Driver/src/CKobuki.h b/src/C++/Driver/src/CKobuki.h index 6d326b5..e190bb0 100755 --- a/src/C++/Driver/src/CKobuki.h +++ b/src/C++/Driver/src/CKobuki.h @@ -208,7 +208,7 @@ private: // utilities long double gyroToRad(signed short GyroAngle); - plot p; + // plot p; std::vector vectorX; std::vector vectorY; std::vector vectorGyroTheta; From 0ee71baa98f27dcc990f85abd359d231b91fcd45 Mon Sep 17 00:00:00 2001 From: Sam Hos Date: Mon, 23 Sep 2024 14:27:34 +0200 Subject: [PATCH 12/24] remove gnpuplot --- src/C++/Driver/src/CKobuki.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/C++/Driver/src/CKobuki.cpp b/src/C++/Driver/src/CKobuki.cpp index 5cd090f..b581725 100755 --- a/src/C++/Driver/src/CKobuki.cpp +++ b/src/C++/Driver/src/CKobuki.cpp @@ -4,7 +4,7 @@ #include #include -plot p; +// plot p; static std::vector vectorX; static std::vector vectorY; static std::vector vectorGyroTheta; @@ -578,9 +578,9 @@ long CKobuki::loop(void *user_data, TKobukiData &Kobuki_data) { vectorY.push_back(gy); vectorGyroTheta.push_back(gyroTheta); - if (counter % 100 == 0) { - p.plot_data(vectorY, vectorX); - } + // if (counter % 100 == 0) { + // p.plot_data(vectorY, vectorX); + // } counter++; return 0; From aa09e0d1876bb1f5ce9fb39af818b1729e5807c1 Mon Sep 17 00:00:00 2001 From: Sam Hos Date: Tue, 24 Sep 2024 14:07:35 +0200 Subject: [PATCH 13/24] Takelijstje --- docs/Infrastructure/taken.md | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 docs/Infrastructure/taken.md diff --git a/docs/Infrastructure/taken.md b/docs/Infrastructure/taken.md new file mode 100644 index 0000000..8ad7ef2 --- /dev/null +++ b/docs/Infrastructure/taken.md @@ -0,0 +1,10 @@ +# Taken + + +* [ ] 2 way socket schrijven voor pi en server (maybe 1 taal maybe 2 talen) +- [ ] Data van kobuki omzetten naar json en versturen naar server via socket +- [ ] Website bouwen en data er op displayen +- [ ] De kobuki vanaf de website besturen + * [ ] Zorg er voor dat de pi de kobuki kan besturen + * [ ] Zorg er voor dat de website naar de server een commando kan sturen + * [ ] Zorg er voor dat de server het commando naar de pi kan sturen From a49800ca5114cd92efcbdb8c9cab2a985b387746 Mon Sep 17 00:00:00 2001 From: Sam Hos Date: Tue, 24 Sep 2024 14:41:11 +0200 Subject: [PATCH 14/24] Websocket server cpp --- src/Socket/main.cpp | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 src/Socket/main.cpp diff --git a/src/Socket/main.cpp b/src/Socket/main.cpp new file mode 100644 index 0000000..2d36667 --- /dev/null +++ b/src/Socket/main.cpp @@ -0,0 +1,33 @@ +#include +#include +#include +#include +#include + +int serverSocket = socket(AF_INET, SOCK_STREAM, 0); + +using namespace std; + +int main() +{ + sockaddr_in serverAddress; + serverAddress.sin_family = AF_INET; + serverAddress.sin_port = htons(4204); + serverAddress.sin_addr.s_addr = INADDR_ANY; + + bind(serverSocket, (struct sockaddr *)&serverAddress, sizeof(serverAddress)); + + listen(serverSocket, 5); + + int clientSocket = accept(serverSocket, nullptr, nullptr); + + char buffer[1024] = {0}; + recv(clientSocket, buffer, sizeof(buffer), 0); + cout << "Message from client: " << buffer << endl; + + + close(serverSocket); + return 0; +} + +// https://www.geeksforgeeks.org/socket-programming-in-cpp/ \ No newline at end of file From 5badea0c32eb99a7f6d528f96637215a936ac462 Mon Sep 17 00:00:00 2001 From: Sam Hos Date: Tue, 24 Sep 2024 14:41:20 +0200 Subject: [PATCH 15/24] threaded the movement of the robot --- src/C++/Driver/src/main.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/C++/Driver/src/main.cpp b/src/C++/Driver/src/main.cpp index 7feb324..a12d8b9 100644 --- a/src/C++/Driver/src/main.cpp +++ b/src/C++/Driver/src/main.cpp @@ -16,6 +16,7 @@ int main() cout << "Enter commando"; thread mv(movement); usleep(30 * 1000 * 1000); + mv.join(); //only exit once thread one is done running } int checkCenterCliff() @@ -35,7 +36,7 @@ int movement() if (text == 1) { - robot.goStraight(1); + robot.goStraight(10); } else if (text == 2) { @@ -59,4 +60,4 @@ int movement() } } } -} \ No newline at end of file +} From 4bef1a61fe1cf590fdb3e4e968b7da08433261dc Mon Sep 17 00:00:00 2001 From: Sam Hos Date: Tue, 24 Sep 2024 14:41:44 +0200 Subject: [PATCH 16/24] Infrastructure.md --- docs/Infrastructure/infrastructure.md | 31 +++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 docs/Infrastructure/infrastructure.md diff --git a/docs/Infrastructure/infrastructure.md b/docs/Infrastructure/infrastructure.md new file mode 100644 index 0000000..4102344 --- /dev/null +++ b/docs/Infrastructure/infrastructure.md @@ -0,0 +1,31 @@ +# Infrastructure + +```mermaid +classDiagram + +VirtualMachine <--> RPI + +namespace Server { + class VirtualMachine { + +Apache() + +Websocket() + +MariaDB() + Python/C++ + Database + Website + + + } +} +namespace kobuki { + class RPI { + Receiver + Sensors + C++ + +Websocket() + +Kobuki() + + } + +} +``` \ No newline at end of file From 92ca442431e6a846d9fb55290174163eb303697b Mon Sep 17 00:00:00 2001 From: Sam Hos Date: Tue, 24 Sep 2024 15:10:42 +0200 Subject: [PATCH 17/24] Reorganisation --- .gitignore | 5 +++ src/C++/Driver/cmake_install.cmake | 2 +- src/C++/Socket/a.out | Bin 0 -> 16520 bytes src/{ => C++}/Socket/main.cpp | 0 src/C++/main.cpp | 60 ----------------------------- src/C++/main.o | Bin 32680 -> 0 bytes src/C++/makefile | 18 --------- src/C++/progr | Bin 25888 -> 0 bytes 8 files changed, 6 insertions(+), 79 deletions(-) create mode 100755 src/C++/Socket/a.out rename src/{ => C++}/Socket/main.cpp (100%) delete mode 100644 src/C++/main.cpp delete mode 100644 src/C++/main.o delete mode 100644 src/C++/makefile delete mode 100755 src/C++/progr diff --git a/.gitignore b/.gitignore index f384d63..ea865e6 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,8 @@ src/C++/progr src/C++/Driver/odometry.txt src/C++/Driver/CMakeCache.txt src/C++/Driver/kobuki_control +src/C++/Driver/cmake_install.cmake +src/C++/Driver/vgcore.42436 +src/C++/Driver/vgcore.42611 +src/Socket/a.out +src/C++/Driver/cmake_install.cmake diff --git a/src/C++/Driver/cmake_install.cmake b/src/C++/Driver/cmake_install.cmake index 45179d9..fced060 100644 --- a/src/C++/Driver/cmake_install.cmake +++ b/src/C++/Driver/cmake_install.cmake @@ -12,7 +12,7 @@ if(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME) string(REGEX REPLACE "^[^A-Za-z0-9_]+" "" CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}") else() - set(CMAKE_INSTALL_CONFIG_NAME "") + set(CMAKE_INSTALL_CONFIG_NAME "DEBUG") endif() message(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"") endif() diff --git a/src/C++/Socket/a.out b/src/C++/Socket/a.out new file mode 100755 index 0000000000000000000000000000000000000000..457375ba5723e7919389e5f529e47e2be9c67997 GIT binary patch literal 16520 zcmeHOeQ;b=6~DV_+5l~mVk2n_bg6)?wcC6(2AImG$)<0iEip;8bf~YJ-IrwTW;gD> z)D|5H)_^e+Co&2hh8gi=6l5Gaq6`!U0(Dxdjush#aU2Z{jLA@G5Y*yF*Ymsgp3U3G zE`$BU(ed4#_s%`P^KtJx@9W-u=iUo;ulCv$wP{eRFxO~g|tHBWkg|Di%JoCv4RCt?jb1bN|y7rgsDCb*p)-1c{g3F z`@xju`St=ZrV^0*JY5C_DomYrh|T1BDHfBP3h7B5mkK@@-7mnfyHDHQr|pqL0H(LnK29$-NM6yZzeEP206TQ?!B7{i+>5m-affT_7Oc2sdp~uwcsVeT?i7 zm-kxuGS)6? zwPpJb;U5uGz}Vg=d}WrYQd561Y*K-9M22Qn6f&gs4KL z8jev+vwtw1GP8CxW1FThBR$*9xRtT`6It8J^lWQOrc+i=v^QxfS#im(ZoA1!#gma( zw_RT!8;E91I}=UV*+?uL?jo$QH=0ev%yibySkb{qkJ(dahP#`o!Cl+C)5&bOv!km! z-ED>m=(Zc`6X~o;CYDL}O(vQ-U?x%td!H00vyu1KNUVpN*l2cMACq=XvGlM_$4iGA z+iS)K_L_asL{ju7QgJb0r&C#xO~>|Hw#Zm9Y6&gJbX*3biIhkpA}JEY_D9XWL@Jt0 z+-!+xEM^VaB9=^NEmG;t+VR-Bb-1yc!4BqY{W0ofnzwF<{GN5#Uvy|BP~pJoMC41g1J|!mDXVqh&gXT&fy?oT z)D~im1E&*{FLe%_hcpnjIPePq=n@L43i`iTV<1LIF~IeyQh>MjBH%^9i+~q_|H}xx zS#{~(jDx2tjPddl8|XDLI%WHFCyj$YsW>X*k=yuFf^%2=oc2|#LR14k0NLzxj>;8J zgU73K_N3&GfX6Fxc1rR;1dmta>|x1&A3R=(v-e8=Tj233oSl^X-QY1qm>rS)9pLfW znjMn-m%(F5FuObNIG*}HM#i4~q%rogaqyM7&Yp1nRQ(BKV$*L(Cs*@a zP>8qsf>o=&NGu)j#HJg`fiY3u1#;CHyM{vXFexDv=jEoWR*gXKsHUX9R_bqD4YKyE zF*avB_4>8OQ)kKy-!bFav-UD_FsdC?A4^Z}-vp{vPd{uj72c-)ukW?jRq=t*7cJvT`~R1?rVf`O7T_KUIO zGnbI^c==wEJ%Lk1$Y&*jm>q%P6W9^FjNq}+-;%X4@%1?(k3jI~2=@N%=)Vtx1k(_VJ#9>k!VP8>y)RKIb>K8ee8CPI?2^4rONa<^2N zd7k3A`>2eqyf^Z91G?=MF9Kc!ya;#^@FL(vz>9zv0WShx1iT3RZ$<#$8May3Y_#7B z^kve6fmkwOrR=K%!Y8u=d@IYY!M9lXU-eurhnfFjqMbzVeKxg<#LCK&JjIH z6b0WlQG7Rd3E%!|-^#^{Dkf>p1svb>cao1Qq0qjl8su`?(9Yy( zDn`V$E3Wxa(K2~uT$ z57AnZ%m2;UzC+1j;uS9fUIe@dcoFa-;6=cTfENKT0$v2X2>d4^zTn}UzmrXU`~bd=d-yq z=#)-^;@qagy23eMGg{8MOpodQaSl^0oKUGzB)`{YVn*k4;maM$oFe)8CO#CST%?Go z*2z?iSLhCNzbkb6oO8wP(+5X+Jmf~I(&tUdAJUHK3!&um{m^_;%iq>Ked7GDD4aj; z?o6{j!5x}@T+=>H_i1{Yrgv)kT}>a>^q8jXe`iS5wzRcf9auxz%WDJmO~Hm>eW0PP zp{cH=PUb_h_B$y~%L4I+{5b8D;=1vRN^x2z?OmpYSf1dcY{?Y?1?bZ%k{Vy>!oQ*M zi(UAy2#0^Z|MsaJ}O(g$d z3H`k#@Gq6XzYW|^PgU1-{}Q!nx@ppr z&kP%8M_22%uxYe+3A6pi?XBA)ZF##JIy$<;lwaSvd285IiR~eoS5CR)NE=7KdjVit z@u(fu$?pXcmD^qbAveANFe5iml6*XoGKaHP+?5?)ped8+k==i8D+QDo|-PQ$+NwSQUjKVb(@t8a3D#pt` z+UT(=OD#SBP?+*~S)udecjiAp6$~BOzD3(J4Y8u8Jbq=knJP~E{o0->zOOh7zn2(` zP{nC~kG5wTU`0*c_Mag9FEr-m{_{M5DYwt_0C)eRWRI~H+w(ku=`#o}74#8Rw&(GB zf-rQM?Rnn8l;;_wB8zs%toSt5Fs5gF9>+7~@dNjt^_YI1>@i1Rp63ZnhjdFEW9~n9 zV1g=$Dck4gDO!=|DcnBW^YP!M?Kf+OJnvyTr*YV0ZsfNACSiyP`_GSS^!SG7gQOyh z`~2gZn$td@?U)|cc1*N5-^}-1_PqX>>Gd2K?SSps-w#~&JWgcF^Ig_=_x~YnpKm6h zH8s6NvrOFfkC6b!&-Q_U(qxKno6h34KS4sL{my{WX8O3(nCg7~7=Df_m9**Gc7DC_ zdZpox7uz%aJ*ibW?0KGlueN7BsH2K?wNTOOc`4hw?>~0uq -#include -#include -#include -#include - - -int main() { - char byte; - bool foundAA = false; - std::vector buffer; - std::ifstream f("/dev/ttyUSB0", std::ios::binary); - if (!f.is_open()) { - std::cerr << "Failed to open the file" << std::endl; - return 1; - } - - while (f.read(&byte, 1)) { - unsigned char ubyte = static_cast(byte); - buffer.push_back(ubyte); - if (foundAA) { - if (ubyte == 0b01010101) { // 0x55 - std::cout << "Found 0xAA followed by 0x55" << std::endl; - // std::cout << "Buffer size" << buffer.size() << std::endl << std::endl; - // Print the buffer in hex values - for (int i = 0; i < 4; i++) { - std::cout << "0x" << std::hex << std::setw(2) << std::setfill('0') << static_cast(static_cast(buffer[i])) << " "; - } - //reset buffer after new 0XAA and 0x55 is found - buffer.clear(); - foundAA = false; // Reset the state - if (ubyte == 0b10101010) - foundAA = true; - } else { - foundAA = false; // Reset the state if the next byte is not 0x55 - } - } else if (ubyte == 0b10101010) { // 0xAA - foundAA = true; - } - - - } - - f.close(); - return 0; -} - - - -//Tomorrow -//Try to use vectors and store every byte in its own array object by dividing the buffer into 8 bits - - - - -//Tomorrow -//Try to use vectors and store every byte in its own array object by dividing the buffer into 8 bits \ No newline at end of file diff --git a/src/C++/main.o b/src/C++/main.o deleted file mode 100644 index d2cd5c527e8ea173fcc9ab99c9e0dc2446bc4004..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32680 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 JeKP6%{{u)n=*9p5 diff --git a/src/C++/makefile b/src/C++/makefile deleted file mode 100644 index af7de6e..0000000 --- a/src/C++/makefile +++ /dev/null @@ -1,18 +0,0 @@ -#clean this up for seperate build folder -CPPFLAGS = -Wall -I./include -CC=g++ - -#target : main.o -# g++ * -Wall -progr: main.o - $(CC) $^ $(CPPFLAGS) -o progr #S^ stands for all dependencies - @echo "ready" - -main.o: main.cpp #may be omitted (implicit rule) - $(CC) $(CPPFLAGS) -c -o main.o main.cpp - -clean: - rm progr - rm *.o - - diff --git a/src/C++/progr b/src/C++/progr deleted file mode 100755 index 4984e9b64e21747ac5fa570888410e28aaf11144..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25888 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 q77Zwe52%8XcMqCwf_bk(5$2Y From b7e8f428c9c0401e56d9e366bb9508fd1c93809b Mon Sep 17 00:00:00 2001 From: Sam Hos Date: Tue, 24 Sep 2024 15:14:21 +0200 Subject: [PATCH 18/24] Changes to gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index ea865e6..af947b8 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ src/C++/main.o src/C++/progr .vscode/settings.json +.vscode src/C++/Driver/odometry.txt src/C++/Driver/CMakeCache.txt src/C++/Driver/kobuki_control From 73e722044c086132e35e3ab95ba4384ed5a6c120 Mon Sep 17 00:00:00 2001 From: Sam Hos Date: Wed, 25 Sep 2024 15:02:22 +0200 Subject: [PATCH 19/24] File creation --- src/Python/socket/socketServer.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 src/Python/socket/socketServer.py diff --git a/src/Python/socket/socketServer.py b/src/Python/socket/socketServer.py new file mode 100644 index 0000000..aff8942 --- /dev/null +++ b/src/Python/socket/socketServer.py @@ -0,0 +1,21 @@ +import socket + + +HOST = "127.0.0.1" # Standard loopback interface address (localhost) +PORT = 4024 # Port to listen on (non-privileged ports are > 1023) + +with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: + s.bind((HOST, PORT)) + s.listen() + conn, addr = s.accept() + with conn: + print(f"Connected by {addr}") + conn.sendall(b"hallo") + while True: + data = conn.recv(2048) + conn.sendall(input("Enter message: ").encode()) + if (data): + print("received", repr(data)) + if not data: + break + conn.sendall(data) \ No newline at end of file From d5407138f208c694ccd68df01f3da1648e02d5f5 Mon Sep 17 00:00:00 2001 From: Sam Hos Date: Wed, 25 Sep 2024 15:02:41 +0200 Subject: [PATCH 20/24] Made cpp into client instead of server --- src/C++/Socket/main.cpp | 65 +++++++++++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 22 deletions(-) diff --git a/src/C++/Socket/main.cpp b/src/C++/Socket/main.cpp index 2d36667..2ccb171 100644 --- a/src/C++/Socket/main.cpp +++ b/src/C++/Socket/main.cpp @@ -1,33 +1,54 @@ -#include #include -#include -#include -#include +#include +#include -int serverSocket = socket(AF_INET, SOCK_STREAM, 0); +using boost::asio::ip::tcp; -using namespace std; +int main() { + try { + // Object creation + boost::asio::io_context io_context; -int main() -{ - sockaddr_in serverAddress; - serverAddress.sin_family = AF_INET; - serverAddress.sin_port = htons(4204); - serverAddress.sin_addr.s_addr = INADDR_ANY; + // Resolve the server address and port + tcp::resolver resolver(io_context); + tcp::resolver::results_type endpoints = resolver.resolve("127.0.0.1", "4024"); - bind(serverSocket, (struct sockaddr *)&serverAddress, sizeof(serverAddress)); + // Create and connect the socket + tcp::socket socket(io_context); + boost::asio::connect(socket, endpoints); - listen(serverSocket, 5); + std::cout << "Connected to the server." << std::endl; - int clientSocket = accept(serverSocket, nullptr, nullptr); + // Receive initial message from the server + boost::asio::streambuf buffer; + boost::asio::read_until(socket, buffer, "\n"); + std::istream is(&buffer); + std::string initial_message; + std::getline(is, initial_message); + std::cout << "Initial message from server: " << initial_message << std::endl; - char buffer[1024] = {0}; - recv(clientSocket, buffer, sizeof(buffer), 0); - cout << "Message from client: " << buffer << endl; + // Send and receive messages + while (true) { + // Send a message to the server + std::string message; + std::cout << "Enter message: "; + //read directly from the console and feed with cin to the message variable + std::getline(std::cin, message); + message += "\n"; // Add newline to mark the end of the message + boost::asio::write(socket, boost::asio::buffer(message)); + // Receive a response from the server + boost::asio::streambuf response_buffer; + boost::asio::read_until(socket, response_buffer, "\n"); + std::istream response_stream(&response_buffer); + std::string reply; + std::getline(response_stream, reply); + std::cout << "Reply from server: " << reply << std::endl; + } + + } catch (std::exception& e) { + std::cerr << "Exception: " << e.what() << std::endl; + } - close(serverSocket); return 0; -} - -// https://www.geeksforgeeks.org/socket-programming-in-cpp/ \ No newline at end of file +} \ No newline at end of file From 9ab68f116095297e6217d71291f447217807db99 Mon Sep 17 00:00:00 2001 From: Sam Hos Date: Wed, 25 Sep 2024 15:02:48 +0200 Subject: [PATCH 21/24] Added more details --- docs/Infrastructure/infrastructure.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/Infrastructure/infrastructure.md b/docs/Infrastructure/infrastructure.md index 4102344..46fd4a2 100644 --- a/docs/Infrastructure/infrastructure.md +++ b/docs/Infrastructure/infrastructure.md @@ -8,7 +8,7 @@ VirtualMachine <--> RPI namespace Server { class VirtualMachine { +Apache() - +Websocket() + +WebsocketServer() +MariaDB() Python/C++ Database @@ -22,7 +22,7 @@ namespace kobuki { Receiver Sensors C++ - +Websocket() + +WebsocketClient() +Kobuki() } From ecee55464092e791602ca1aaaa698fc98d6edc07 Mon Sep 17 00:00:00 2001 From: Sietse Jonker Date: Wed, 25 Sep 2024 16:29:06 +0200 Subject: [PATCH 22/24] test --- src/C++/Socket/a.out | Bin 16520 -> 16024 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/src/C++/Socket/a.out b/src/C++/Socket/a.out index 457375ba5723e7919389e5f529e47e2be9c67997..701da2ece8bd45ea7f034904af779e2128035101 100755 GIT binary patch delta 2605 zcmZ`*eQZ-z6u+eIugG~G>$0LbKkpnfhFGN-rqgH zbMATX-E+>pJ$6_)ad6Otd;`(QUFT7}vp6%b^9Ll=|Z|N&c^n=t6g4rb`VaQ+=4$x72 z8#T+|tgZm24L0GJsu@tnbLtqSBMcgBP$w$F`>Hf5ZiWq6B~OME$w;&_9Npa+?uf*@ z$nIoMcY-8(qMflMNhEu_V%;PW>)u7e;jZ}8QEJ|s3_lx*cOw(s9|?EFyCYrk12Gcq z>Pg_()7>45CgEPz2H2XtBBdufVjv>EIsNgyrgIuF8Y>6(b#rf`N+iGHoHl{z$xTES zOHvq*=MwbuFXPS)y@4^(lPug2YO}8-ZX)Piq8o&b2iw@9$z)K{CL=7GETc$}@xh>` zpXZr85zu&=5qcOfTJ3bk+tdSEGklENMO=kA^ME!7MAJsW0Ien~^qF#U9YM`78zCDG znyhyIWXijPbVLpI+%ZqVx7o)n!!TuWZq~a9`LjdLD?h3lCkYh$+RIJLkuDwzLUuuf+rl0EeRsC92v4c zTg^(kVm0=W->Jpxjz@~`qQzNi(X`m|imo{~OZQ$*wh_bkHGO<(isvBDIhLzxA<$)9 zzCs0TT)w7>^D-?A+Hy3QuM(^fwYB7HXlF7jh7wZB2%c&sOdbJ`>~gwAP2>qaL-zxl zSp%{J4$A>y1TM+t%LZv?Vq-w2*dp$Ef`HB?d-gIKlc$H8)7+p9H%gVaF#TO7>+xty z=|+8cmK7g&*I`L(EeP%Ir+fmIdVxb@_}_8(zvW4%)l${@bhCGi^I zxD8Gt%PWQB61a^lPiBr~u%f{w@e<&;6XFf7d|odcv0lzJ$PzCrjw5ipA!R(oHWj2s zE4n^PnXkZZvKXieZJ%CGk|}SOIZlgAUCn$38gibAiq82BY5s zZP+XQZWAwuQHc0!C4Lo7-~~ckC7kvLgl%x!?=ta(r~_x9R^s7S+?u5kn#2O=tIq+q x!2quX3IzpD1p-C8ncmG#nldyu!C!%D^NCg3$_^b=1=pDGdo{6GfIam~{{sv9)LQ@m literal 16520 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 Date: Wed, 25 Sep 2024 16:41:23 +0200 Subject: [PATCH 23/24] websocket server update --- src/Python/socket/socketServer.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/Python/socket/socketServer.py b/src/Python/socket/socketServer.py index aff8942..252994e 100644 --- a/src/Python/socket/socketServer.py +++ b/src/Python/socket/socketServer.py @@ -1,6 +1,5 @@ import socket - HOST = "127.0.0.1" # Standard loopback interface address (localhost) PORT = 4024 # Port to listen on (non-privileged ports are > 1023) @@ -13,9 +12,8 @@ with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: conn.sendall(b"hallo") while True: data = conn.recv(2048) - conn.sendall(input("Enter message: ").encode()) - if (data): + if data: print("received", repr(data)) + conn.sendall(b"message received") if not data: - break - conn.sendall(data) \ No newline at end of file + break \ No newline at end of file From e2d2c41ad4e7d915759e7b24f5b93db906e731c0 Mon Sep 17 00:00:00 2001 From: Sam Hos Date: Thu, 26 Sep 2024 13:20:46 +0200 Subject: [PATCH 24/24] websocket shenanigans worky --- src/C++/Socket/main.cpp | 3 +-- src/Python/socket/socketServer.py | 9 +++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/C++/Socket/main.cpp b/src/C++/Socket/main.cpp index 2ccb171..1449e3a 100644 --- a/src/C++/Socket/main.cpp +++ b/src/C++/Socket/main.cpp @@ -6,7 +6,7 @@ using boost::asio::ip::tcp; int main() { try { - // Object creation + // Create an io_context object boost::asio::io_context io_context; // Resolve the server address and port @@ -32,7 +32,6 @@ int main() { // Send a message to the server std::string message; std::cout << "Enter message: "; - //read directly from the console and feed with cin to the message variable std::getline(std::cin, message); message += "\n"; // Add newline to mark the end of the message boost::asio::write(socket, boost::asio::buffer(message)); diff --git a/src/Python/socket/socketServer.py b/src/Python/socket/socketServer.py index 252994e..1bff9ef 100644 --- a/src/Python/socket/socketServer.py +++ b/src/Python/socket/socketServer.py @@ -1,19 +1,20 @@ import socket -HOST = "127.0.0.1" # Standard loopback interface address (localhost) +HOST = "127.0.0.1" # Listen on all available interfaces PORT = 4024 # Port to listen on (non-privileged ports are > 1023) with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.bind((HOST, PORT)) s.listen() + print(f"Server listening on {HOST}:{PORT}") conn, addr = s.accept() with conn: print(f"Connected by {addr}") - conn.sendall(b"hallo") + conn.sendall(b"hallo\n") while True: data = conn.recv(2048) if data: - print("received", repr(data)) - conn.sendall(b"message received") + print("Received:", repr(data)) + conn.sendall(b"message received\n") if not data: break \ No newline at end of file