From 1417a65e46f0473924d71b297e3fc3b88cc26aad Mon Sep 17 00:00:00 2001 From: lonkaars Date: Sun, 21 May 2023 18:09:12 +0200 Subject: update references --- doc/dui.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/dui.md b/doc/dui.md index 3f72e1c..07c36c1 100644 --- a/doc/dui.md +++ b/doc/dui.md @@ -286,7 +286,7 @@ All the above algorithms could be used with OpenCV, But the Radon transform need In order to make the Zumo robot both detect where it is on a road, and steer to keep driving on said road, some sort of communication needs to exist between -the Nicla and Zumo. As mentioned earlier\footnote{dit is nog niet benoemd}, all +the Nicla and Zumo. As mentioned in section \ref{distribution-of-features}, all machine vision-related tasks will happen on the Nicla board. Because the Nicla board is the first to know how much to steer the cart, it makes sense to have it control the cart by giving the Nicla a 'steering wheel' of sorts. @@ -353,8 +353,8 @@ The complete protocol consists of single byte commands. A byte can either change the cart speed or steering direction, both will apply gradually. When no commands have been received for more than 2 seconds, the Zumo robot will gradually slow down until it is stopped. Exact specifications of commands are -provided in the protocol specification document\footnote{dit document bestaat -nog niet}. +provided in the protocol specification in section +\ref{niclazumo-communication-protocol}. } \communicationConclusion -- cgit v1.2.3 From 73d5c5e0528466c10e3219334466a3edfbd53266 Mon Sep 17 00:00:00 2001 From: lonkaars Date: Mon, 22 May 2023 11:52:30 +0200 Subject: finish merge of #4 --- doc/base.tex | 3 +++ doc/dui.md | 5 ++--- doc/pandoc.tex | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 3 deletions(-) create mode 100644 doc/pandoc.tex diff --git a/doc/base.tex b/doc/base.tex index edadce3..d51d0c4 100644 --- a/doc/base.tex +++ b/doc/base.tex @@ -18,8 +18,11 @@ bibencoding=utf8, style=apa ]{biblatex} +\usepackage{fancyvrb} \addbibresource{refs.bib} +\input{pandoc.tex} + \setmainfont{TeX Gyre Schola} \setmathfont{TeX Gyre Schola Math} \sisetup{ diff --git a/doc/dui.md b/doc/dui.md index e4d14a3..5cf6630 100644 --- a/doc/dui.md +++ b/doc/dui.md @@ -71,8 +71,7 @@ description in section \ref{problem-statement}. ## Overview -![Architecture overview (level 0) -\label{fig:architecture-level-0}](../assets/architecture-level-0.pdf) +![Architecture overview (level 0)](../assets/architecture-level-0.pdf){#fig:architecture-level-0} Figure \ref{fig:architecture-level-0} shows the hardware used in this project. Both the Pololu Zumo 32U4 (referred to as just "Zumo"), and the Arduino Nicla @@ -494,7 +493,7 @@ Most shape based recognition methods are more complex than using a color based d ## Traffic Sign Recognition (TSR) After traffic sign detection or tracking, traffic sign recognition is performed to classify the detected traffic signs into correct classes. -![signs example](../assets/signs.png) +![signs example](../assets/signs.png){#fig:signs-example} ### Binary tree The binary-tree-based classification method usually classify traffic signs according to the shapes and colors in a coarse-to-fine tree process. diff --git a/doc/pandoc.tex b/doc/pandoc.tex new file mode 100644 index 0000000..2561a57 --- /dev/null +++ b/doc/pandoc.tex @@ -0,0 +1,57 @@ +\newcommand{\VerbBar}{|} +\newcommand{\VERB}{\Verb[commandchars=\\\{\}]} +\DefineVerbatimEnvironment{Highlighting}{Verbatim}{commandchars=\\\{\}} +% Add ',fontsize=\small' for more characters per line +\newenvironment{Shaded}{}{} +\newcommand{\AlertTok}[1]{\textcolor[rgb]{1.00,0.00,0.00}{\textbf{#1}}} +\newcommand{\AnnotationTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textbf{\textit{#1}}}} +\newcommand{\AttributeTok}[1]{\textcolor[rgb]{0.49,0.56,0.16}{#1}} +\newcommand{\BaseNTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{#1}} +\newcommand{\BuiltInTok}[1]{\textcolor[rgb]{0.00,0.50,0.00}{#1}} +\newcommand{\CharTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{#1}} +\newcommand{\CommentTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textit{#1}}} +\newcommand{\CommentVarTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textbf{\textit{#1}}}} +\newcommand{\ConstantTok}[1]{\textcolor[rgb]{0.53,0.00,0.00}{#1}} +\newcommand{\ControlFlowTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{\textbf{#1}}} +\newcommand{\DataTypeTok}[1]{\textcolor[rgb]{0.56,0.13,0.00}{#1}} +\newcommand{\DecValTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{#1}} +\newcommand{\DocumentationTok}[1]{\textcolor[rgb]{0.73,0.13,0.13}{\textit{#1}}} +\newcommand{\ErrorTok}[1]{\textcolor[rgb]{1.00,0.00,0.00}{\textbf{#1}}} +\newcommand{\ExtensionTok}[1]{#1} +\newcommand{\FloatTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{#1}} +\newcommand{\FunctionTok}[1]{\textcolor[rgb]{0.02,0.16,0.49}{#1}} +\newcommand{\ImportTok}[1]{\textcolor[rgb]{0.00,0.50,0.00}{\textbf{#1}}} +\newcommand{\InformationTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textbf{\textit{#1}}}} +\newcommand{\KeywordTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{\textbf{#1}}} +\newcommand{\NormalTok}[1]{#1} +\newcommand{\OperatorTok}[1]{\textcolor[rgb]{0.40,0.40,0.40}{#1}} +\newcommand{\OtherTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{#1}} +\newcommand{\PreprocessorTok}[1]{\textcolor[rgb]{0.74,0.48,0.00}{#1}} +\newcommand{\RegionMarkerTok}[1]{#1} +\newcommand{\SpecialCharTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{#1}} +\newcommand{\SpecialStringTok}[1]{\textcolor[rgb]{0.73,0.40,0.53}{#1}} +\newcommand{\StringTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{#1}} +\newcommand{\VariableTok}[1]{\textcolor[rgb]{0.10,0.09,0.49}{#1}} +\newcommand{\VerbatimStringTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{#1}} +\newcommand{\WarningTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textbf{\textit{#1}}}} + +\makeatletter +\def\fig@maxwidth{10cm} +\def\fig@maxheight{10cm} +\def\ScaleWidthIfNeeded{% + \ifdim\Gin@nat@width>\fig@maxwidth + \fig@maxwidth + \else + \Gin@nat@width + \fi +} +\def\ScaleHeightIfNeeded{% + \ifdim\Gin@nat@height>0.9\fig@maxheight + \fig@maxheight + \else + \Gin@nat@width + \fi +} +\makeatother + +\setkeys{Gin}{width=\ScaleWidthIfNeeded,height=\ScaleHeightIfNeeded,keepaspectratio}% -- cgit v1.2.3 From bb0972183bd568a9e45d447e122d0fba9a587ba9 Mon Sep 17 00:00:00 2001 From: lonkaars Date: Mon, 22 May 2023 12:18:05 +0200 Subject: use biblatex for references (joshua) --- doc/base.tex | 2 +- doc/dui.md | 11 +++++------ doc/refs.bib | 7 +++++++ 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/doc/base.tex b/doc/base.tex index d51d0c4..e8bc8f1 100644 --- a/doc/base.tex +++ b/doc/base.tex @@ -66,7 +66,7 @@ \input{\jobname.md.tex} -% \printbibliography[heading=bibintoc] +\printbibliography[heading=bibintoc] % \printglossaries % \listoftables % \listoffigures diff --git a/doc/dui.md b/doc/dui.md index 5cf6630..22d74a6 100644 --- a/doc/dui.md +++ b/doc/dui.md @@ -415,7 +415,10 @@ fB(i) = max(0, min(iB − iR, iB − iG)/s), fY(i) = max(0, min(iR − iB, iG − iB)/s). ``` -This method can result in some issues on the blue channel (see source 1 page 86583 for more explanation). As a solution to this issue use the following formula for the blue channel instead: +This method can result in some issues on the blue channel +\parencite[86583]{ieee:sign-detection}. As a solution to this issue use the +following formula for the blue channel instead: + ```py f′B(i) = max((0, iB − iR)/s). ``` @@ -449,7 +452,7 @@ This color space is used for finding uncorrelated color components, the L\*a\*b\ This method avoids the use of fixed thresholds that might need adjusting at times. In order to resolve this some authors tried to transfer the problem into pixel classification where a neural network classifies every pixel in the input image, the pixel classification algorithms are often slower than other color extraction methods. -#### results +#### Results \def\signDetectionColor{ The above described methods where also applied to a database in order to compare each method. This resulted in the conclusion that, using a normalized RGB space is giving the a mixture of most detections and least false-positve results. See source 1 page 86584 for the full report. @@ -516,7 +519,3 @@ While making a binary tree is seemingly the most simple, yet effective solution. \signDetectionShape \signRecognition -## Sources: - -1. [IEEE, Digital Object Identifier June 26, 2019 (pages 86578 - 86596)](https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=8746141) - diff --git a/doc/refs.bib b/doc/refs.bib index e69de29..7ae5f95 100644 --- a/doc/refs.bib +++ b/doc/refs.bib @@ -0,0 +1,7 @@ +@article{ieee:sign-detection, + author = {Chunsheng Liu and Shuang Li and Faliang Chang and Yinhai Wang}, + title = {Machine Vision Based Traffic Sign Detection Methods: Review, + Analyses and Perspectives}, + year = {2019}, + url = {https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=8746141} +} -- cgit v1.2.3 From 7493bb9c899c34853d0f7f84f60838583ae19aaf Mon Sep 17 00:00:00 2001 From: lonkaars Date: Mon, 22 May 2023 12:44:46 +0200 Subject: hough transform sources to bibtex --- doc/dui.md | 8 ++++---- doc/refs.bib | 23 +++++++++++++++++++++++ 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/doc/dui.md b/doc/dui.md index 22d74a6..03bd855 100644 --- a/doc/dui.md +++ b/doc/dui.md @@ -195,10 +195,10 @@ This is a popular algorithm used to detect straight lines in an image. It works For more information about Hough Transform algorithms check the below links: -- [Wiki hough](https://en.wikipedia.org/wiki/Hough_transform ) -- [Science article](https://www.sciencedirect.com/topics/computer-science/hough-transforms) -- [OpenCV Hough](https://docs.opencv.org/3.4/d9/db0/tutorial_hough_lines.html) -- [OpenMV find_lines](https://docs.openmv.io/library/omv.image.html) +- \citetitle{wikipedia:hough} +- \citetitle{sciencedirect:hough} +- \citetitle{opencv:hough} +- \citetitle{openmv:find_lines} #### EDlines diff --git a/doc/refs.bib b/doc/refs.bib index 7ae5f95..4af280b 100644 --- a/doc/refs.bib +++ b/doc/refs.bib @@ -5,3 +5,26 @@ year = {2019}, url = {https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=8746141} } + +@online{wikipedia:hough, + title = {Hough transform}, + url = {https://en.wikipedia.org/wiki/Hough_transform} +} + +@article{sciencedirect:hough, + author = {Mark S. Nixon and Alberto S and Aguado}, + title = {Feature Extraction and Image Processing for Computer Vision}, + year = {2020}, + url = {https://www.sciencedirect.com/topics/computer-science/hough-transforms} +} + +@manual{opencv:hough, + title = {Hough Line Transform}, + url = {https://docs.opencv.org/3.4/d9/db0/tutorial_hough_lines.html} +} + +@manual{openmv:find_lines, + title = {image — machine vision}, + url = {https://docs.openmv.io/library/omv.image.html} +} + -- cgit v1.2.3 From 60f7d6edf5c69e8cb5944b5187a246334fe024a0 Mon Sep 17 00:00:00 2001 From: lonkaars Date: Mon, 22 May 2023 17:47:21 +0200 Subject: update all references --- doc/dui.md | 24 ++++++++++----------- doc/refs.bib | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+), 12 deletions(-) diff --git a/doc/dui.md b/doc/dui.md index 03bd855..18dea0c 100644 --- a/doc/dui.md +++ b/doc/dui.md @@ -206,10 +206,10 @@ EDLines, short for Edge Drawing Lines, is a feature-based algorithm that detects For more information about EDlines algorithms check the below links: -- [github library](https://github.com/CihanTopal/ED_Lib) -- [Science article](https://www.sciencedirect.com/science/article/abs/pii/S0167865511001772) -- [EDLINES: REAL-TIME LINE SEGMENT DETECTION BY EDGE DRAWING (ED)](https://projet.liris.cnrs.fr/imagine/pub/proceedings/ICIP-2011/papers/1569406487.pdf) -- [OpenCV EDlines doc](https://docs.opencv.org/3.4/d4/d8b/group__ximgproc__edge__drawing.html) +- \citetitle{gh:ed_lib} +- \citetitle{sciencedirect:edlines} +- \citetitle{paper:edlines} +- \citetitle{opencv:edgedrawing} #### Line Segment Detector @@ -221,10 +221,10 @@ Once the line segments are detected, they are refined using a line merging algor For more information about Line Segment Detector algorithms check the below links: -- [LSD: a Line Segment Detector pdf](http://www.ipol.im/pub/art/2012/gjmr-lsd/article.pdf) -- [Working behind LSD](https://saiwa.ai/blog/line-segment-detection-2/) -- [OpenCV LSD doc](https://docs.opencv.org/3.4/db/d73/classcv_1_1LineSegmentDetector.html) -- [OpenMV find_line_segments](https://docs.openmv.io/library/omv.image.html) +- \citetitle{paper:lsd} +- \citetitle{saiwa:lsd} +- \citetitle{opencv:lsd} +- \citetitle{openmv:lsd} #### Radon transform @@ -232,10 +232,10 @@ Radon transform is another popular algorithm used for line detection. It works b For more information about Radon transform algorithms check the below links: -- [Science article](https://www.sciencedirect.com/science/article/abs/pii/0031320396000155) -- [matlab Radon](https://stackoverflow.com/questions/35412573/radon-transform-line-detection) -- [Matlab elaboration Radon](https://www.kevinpolisano.com/Doctorat/doc-matlab-exemple/radon_lines_detection.html) -- [OpenCV Radon doc](https://docs.opencv.org/4.x/d5/d89/radon__transform_8hpp.html) +- \citetitle{sciencedirect:radon} +- \citetitle{stackoverflow:radon} +- \citetitle{matlab:radon} +- \citetitle{opencv:radon} ### Which algorithm is suitable for our project? diff --git a/doc/refs.bib b/doc/refs.bib index 4af280b..e8a2277 100644 --- a/doc/refs.bib +++ b/doc/refs.bib @@ -28,3 +28,73 @@ url = {https://docs.openmv.io/library/omv.image.html} } +@manual{gh:ed_lib, + title = {Implementations of edge (ED, EDColor, EDPF), line (EDLines), + circle and low eccentric ellipse (EDCircles) detection algorithms.}, + author = {Cihan Topal}, + url = {https://github.com/CihanTopal/ED_Lib} +} + +@article{sciencedirect:edlines, + title = {EDLines: A real-time line segment detector with a false detection control}, + author = {Cuneyt Akinlar}, + url = {https://www.sciencedirect.com/science/article/abs/pii/S0167865511001772} +} + +@article{paper:edlines, + title = {EDLines: real-time line segment detection by edge drawing (ED)}, + author = {Cuneyt Akinlar and Cihan Topal}, + year = {2011}, + url = {https://projet.liris.cnrs.fr/imagine/pub/proceedings/ICIP-2011/papers/1569406487.pdf} +} + +@manual{opencv:edgedrawing, + title = {OpenCV EDlines doc}, + url = {https://docs.opencv.org/3.4/d4/d8b/group__ximgproc__edge__drawing.html} +} + +@article{paper:lsd, + title = {LSD: a Line Segment Detector}, + author = {Rafael Grompone von Gioi and Jérémie Jakubowicz and Jean-Michel Morel and Gregory Randall}, + year = {2012}, + url = {http://www.ipol.im/pub/art/2012/gjmr-lsd/article.pdf} +} + +@online{saiwa:lsd, + title = {line Segment Detection | A Comprehensive Guide}, + year = {2023}, + url = {https://saiwa.ai/blog/line-segment-detection-2/} +} + +@manual{opencv:lsd, + title = {OpenCV LSD doc}, + url = {https://docs.opencv.org/3.4/db/d73/classcv_1_1LineSegmentDetector.html} +} + +@online{openmv:lsd, + title = {OpenMV find\_line\_segments}, + url = {https://docs.openmv.io/library/omv.image.html} +} + +@online{sciencedirect:radon, + title = {A fast digital radon transform -- an efficient means for evaluating the hough transform}, + year = {1996}, + author = {W.A. Götz and H.J. Druckmüller}, + url = {https://www.sciencedirect.com/science/article/abs/pii/0031320396000155} +} + +@online{stackoverflow:radon, + title = {Radon Transform Line Detection}, + url = {https://stackoverflow.com/questions/35412573/radon-transform-line-detection} +} + +@online{matlab:radon, + title = {Radon transform applied to lines detection}, + author = {Kévin Polisano}, + url = {https://www.kevinpolisano.com/Doctorat/doc-matlab-exemple/radon_lines_detection.html} +} + +@online{opencv:radon, + title = {OpenCV Radon doc}, + url = {https://docs.opencv.org/4.x/d5/d89/radon__transform_8hpp.html} +} -- cgit v1.2.3 From 2d4bf042a5e878e3eb0b3d4f8e8941644d8e6f21 Mon Sep 17 00:00:00 2001 From: lonkaars Date: Mon, 22 May 2023 18:21:47 +0200 Subject: editing pass --- doc/base.tex | 10 ++++++---- doc/dui.md | 55 ++++++++++++++++++++++++++++++------------------------- 2 files changed, 36 insertions(+), 29 deletions(-) diff --git a/doc/base.tex b/doc/base.tex index e8bc8f1..c3f36eb 100644 --- a/doc/base.tex +++ b/doc/base.tex @@ -18,8 +18,9 @@ bibencoding=utf8, style=apa ]{biblatex} -\usepackage{fancyvrb} \addbibresource{refs.bib} +\usepackage{fancyvrb} +\usepackage[nottoc]{tocbibind} \input{pandoc.tex} @@ -66,10 +67,11 @@ \input{\jobname.md.tex} +\newpage \printbibliography[heading=bibintoc] -% \printglossaries -% \listoftables -% \listoffigures +\printglossaries +\listoftables +\listoffigures \end{document} diff --git a/doc/dui.md b/doc/dui.md index 18dea0c..6260fb5 100644 --- a/doc/dui.md +++ b/doc/dui.md @@ -243,7 +243,7 @@ We have identified four different types of line detection algorithms that could #### OpenMV -The only two algorithms that work with OpenMV are Hough Transform, the function find_lines, and Line Segment Detector, also known as find_line_segments. Both of these have their ups and downs and could be used for our project. find_lines has the most ups whereas find_line_segemtns has the most negative. As the result here below is decently optimized, it is first grayscaled, and then canny edge detection is done to it. +The only two algorithms that work with OpenMV are Hough Transform, the function `find_lines`, and Line Segment Detector, also known as `find_line_segments`. Both of these have their ups and downs and could be used for our project. `find_lines` has the most ups whereas `find_line_segments` has the most negative. As the result here below is decently optimized, it is first grayscaled, and then canny edge detection is done to it. For the test are the straight lines pictures used with different lighting additionality the left lane represents a whitish line and the right lane is drawn with a more darker color. here below are the pictures used: @@ -251,9 +251,9 @@ For the test are the straight lines pictures used with different lighting additi ![picture 2](../RealTime_pictures/rtStraightLines.class/00018.jpg) -##### find_lines +##### `find_lines` -The find_lines is a very fast function where you can handle straight lines and other lines with at least 45 FPS or more. Also, have a lot of control over the different types of parameters. +The `find_lines` is a very fast function where you can handle straight lines and other lines with at least 45 FPS or more. Also, have a lot of control over the different types of parameters. This is the outcome of picture 1: ![outcome_picture_1](../assets/hough_straightLines_Pic_0.png) @@ -263,9 +263,9 @@ This is the outcome of picture 2: As you can see there isn't much of a difference between the two pictures. -##### find_line_segments +##### `find_line_segments` -The find_line_segments is a very slow function where you can find segments from a line. This is a easier to use function because it only has two parameters but the frame rate drops significantly. Additionally, the size of the image to run the algorithm on needs to be smaller because of memory. +The `find_line_segments` is a very slow function where you can find segments from a line. This is a easier to use function because it only has two parameters but the frame rate drops significantly. Additionally, the size of the image to run the algorithm on needs to be smaller because of memory. This is the outcome of picture 1: @@ -394,6 +394,7 @@ The distinct color characteristics of traffic signs can attract drivers’ atten One can easily look at the RGB values to detect a certain color. Although the r,g and b values are heavily effected by different illuminations, therefore this isn't a reliable solution in variating lighting conditions. +\needspace{5cm} An example implementation: ```py @@ -407,6 +408,7 @@ if(B >= thB) if((R + G) >= ThY) ``` +\needspace{4cm} It is possible to enhance the colors with maximum and minimum operations: ```py @@ -415,16 +417,18 @@ fB(i) = max(0, min(iB − iR, iB − iG)/s), fY(i) = max(0, min(iR − iB, iG − iB)/s). ``` +\needspace{2cm} This method can result in some issues on the blue channel -\parencite[86583]{ieee:sign-detection}. As a solution to this issue use the +\footcite[86583]{ieee:sign-detection}. As a solution to this issue use the following formula for the blue channel instead: ```py -f′B(i) = max((0, iB − iR)/s). +_fB(i) = max((0, iB − iR)/s). ``` #### HSV +\needspace{6cm} The HSV/HSI color space is more immune to the illumination challenges of RGB. The hue and saturation channels can be calculated using RGB, which increases the processing time. The following pseudo code shows how to detect the red, blue and yellow colors in this space. @@ -452,12 +456,13 @@ This color space is used for finding uncorrelated color components, the L\*a\*b\ This method avoids the use of fixed thresholds that might need adjusting at times. In order to resolve this some authors tried to transfer the problem into pixel classification where a neural network classifies every pixel in the input image, the pixel classification algorithms are often slower than other color extraction methods. -#### Results - -\def\signDetectionColor{ -The above described methods where also applied to a database in order to compare each method. This resulted in the conclusion that, using a normalized RGB space is giving the a mixture of most detections and least false-positve results. See source 1 page 86584 for the full report. +\def\signDetectionColorConclusion{ +All color-based detection methods where also applied to a database in order to +compare each method. Experiments concluded that using a normalized RGB space is +giving the a mixture of most detections and least false-positve +results\footcite{ieee:sign-detection}. } -\signDetectionColor +\signDetectionColorConclusion ### Shape based @@ -486,12 +491,12 @@ For example, using a color based detection to find a ROI and using shape detecti ### Neural networks -### results - -\def\signDetectionShape{ -Most shape based recognition methods are more complex than using a color based detection. But the method 'Fourier' seems the most useful as it can also deal with rotated and occluded objects. +\def\signDetectionShapeConclusion{ +Most shape based recognition methods are more complex than using a color based +detection. But the method `Fourier' seems the most useful as it can also deal +with rotated and occluded objects. } -\signDetectionShape +\signDetectionShapeConclusion ## Traffic Sign Recognition (TSR) After traffic sign detection or tracking, traffic sign recognition is performed to classify the detected traffic signs into correct classes. @@ -504,18 +509,18 @@ The binary-tree-based classification method usually classify traffic signs accor ### Support Vector Machine (SVM) As a binary-classification method, SVM classifies traffic signs using one-vs-one or one-vs-others classification process. -## results - -\def\signRecognition{ -While making a binary tree is seemingly the most simple, yet effective solution. Using the 'Fourier' method is a bit more complex, it may be a better solution (this requires testing). +\def\signRecognitionConclusion{ +While making a binary tree is seemingly the most simple, yet effective +solution. Using the `Fourier' method is a bit more complex, it may be a better +solution (this requires testing). } -\signRecognition +\signRecognitionConclusion # Conclusion \communicationConclusion \buildSystemConclusion -\signDetectionColor -\signDetectionShape -\signRecognition +\signDetectionColorConclusion +\signDetectionShapeConclusion +\signRecognitionConclusion -- cgit v1.2.3 From 3b184a992b5da004027f6c26d750fbc848af4cca Mon Sep 17 00:00:00 2001 From: lonkaars Date: Tue, 23 May 2023 13:22:18 +0200 Subject: add version control table to title page --- doc/.gitignore | 1 + doc/base.tex | 7 +++---- doc/makefile | 5 ++++- doc/versiontable.awk | 15 +++++++++++++++ 4 files changed, 23 insertions(+), 5 deletions(-) create mode 100755 doc/versiontable.awk diff --git a/doc/.gitignore b/doc/.gitignore index e5139ef..8e7ebcc 100644 --- a/doc/.gitignore +++ b/doc/.gitignore @@ -17,3 +17,4 @@ # ignore output files *.pdf +versionctl.tex diff --git a/doc/base.tex b/doc/base.tex index c3f36eb..74bb57a 100644 --- a/doc/base.tex +++ b/doc/base.tex @@ -21,15 +21,12 @@ \addbibresource{refs.bib} \usepackage{fancyvrb} \usepackage[nottoc]{tocbibind} +\usepackage[en-US]{datetime2} \input{pandoc.tex} \setmainfont{TeX Gyre Schola} \setmathfont{TeX Gyre Schola Math} -\sisetup{ - group-separator = {.}, - output-decimal-marker = {,} -} \bigskipamount=7mm \medskipamount=4mm @@ -60,6 +57,8 @@ \begin{titlepage} \maketitle \thispagestyle{empty} +\vfill +\input{versionctl.tex} \end{titlepage} \tableofcontents diff --git a/doc/makefile b/doc/makefile index 3446eeb..ebf02f3 100644 --- a/doc/makefile +++ b/doc/makefile @@ -8,13 +8,16 @@ dui.pdf: ../assets/LSD_straightLines_Pic_1.png dui.pdf: ../assets/hough_straightLines_Pic_0.png dui.pdf: ../assets/hough_straightLines_Pic_1.png +versionctl.tex: + git tag -l 'doc-*' --format='%(refname:short) %(objectname:short=7) %(contents:subject) %(*authordate:format:%s)' | ./versiontable.awk -F' ' > $@ + %.png: %.bmp convert $< $@ %.pdf: %.svg rsvg-convert -f pdf -o $@ $< -%.pdf: %.tex base.tex %.md.tex +%.pdf: %.tex base.tex %.md.tex versionctl.tex latexmk $< -shell-escape -halt-on-error -lualatex -f -g %.md.tex: %.md diff --git a/doc/versiontable.awk b/doc/versiontable.awk new file mode 100755 index 0000000..96108fd --- /dev/null +++ b/doc/versiontable.awk @@ -0,0 +1,15 @@ +#!/bin/awk -f +BEGIN { + print "\\noindent\\begin{tabularx}{\\linewidth}{llXr}" + print "\\toprule" + print "Version & Commit & Notes & Date\\\\" + print "\\midrule" +} +{ + sub("doc-", "", $1) + print $1" & \\texttt{"$2"} & "$3" & \\DTMdisplaydate"strftime("{%Y}{%m}{%d}{-1}", $4)"\\\\" +} +END { + print "\\bottomrule" + print "\\end{tabularx}" +} -- cgit v1.2.3 From d53f4014ab90dc09f6b9fff68391fc90a084de59 Mon Sep 17 00:00:00 2001 From: lonkaars Date: Tue, 23 May 2023 13:28:29 +0200 Subject: fix commit pointer in version table --- doc/makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/makefile b/doc/makefile index ebf02f3..fbc2d82 100644 --- a/doc/makefile +++ b/doc/makefile @@ -9,7 +9,7 @@ dui.pdf: ../assets/hough_straightLines_Pic_0.png dui.pdf: ../assets/hough_straightLines_Pic_1.png versionctl.tex: - git tag -l 'doc-*' --format='%(refname:short) %(objectname:short=7) %(contents:subject) %(*authordate:format:%s)' | ./versiontable.awk -F' ' > $@ + git tag -l 'doc-*' --format='%(refname:short) %(*objectname:short) %(contents:subject) %(*authordate:format:%s)' | ./versiontable.awk -F' ' > $@ %.png: %.bmp convert $< $@ -- cgit v1.2.3 From 4568db72dc3f9694ecae3506fc3de6ffc948b24f Mon Sep 17 00:00:00 2001 From: lonkaars Date: Wed, 24 May 2023 15:51:25 +0200 Subject: WIP zumo<-nicla communication --- nicla/serial_test.py | 21 +++++++++++++++++++++ zumo/zumo.ino | 7 +++++-- 2 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 nicla/serial_test.py diff --git a/nicla/serial_test.py b/nicla/serial_test.py new file mode 100644 index 0000000..bef43a2 --- /dev/null +++ b/nicla/serial_test.py @@ -0,0 +1,21 @@ +from pyb import Pin, delay + +zumo_tx = Pin("PA10", Pin.IN) +zumo_rx = Pin("PA9", Pin.OUT_PP) + +def uart_send(s): + zumo_rx.value(0) + byte = ord(s) + print("START BIT") + delay(2) + for x in range(8): + bit = (byte & (1 << 7)) >> 7 + byte <<= 1 + zumo_rx.value(bit) + print(f"BIT[{x}] = {bit}") + delay(2) + print("STOP BIT") + zumo_rx.value(1) + +while True: + uart_send("a") diff --git a/zumo/zumo.ino b/zumo/zumo.ino index f59bd36..c65c2f9 100644 --- a/zumo/zumo.ino +++ b/zumo/zumo.ino @@ -5,6 +5,9 @@ #include "protocol.h" #include "pid.h" +#define DUI_PINOUT_NICLA_TX 13 +#define DUI_PINOUT_NICLA_RX 14 + dui_state_t g_dui_target_state = { .steer = 1.0f, .speed = 1.0f, @@ -19,6 +22,8 @@ dui_state_t g_dui_current_state = { }; void setup() { + pinMode(DUI_PINOUT_NICLA_TX, OUTPUT); + pinMode(DUI_PINOUT_NICLA_RX, INPUT_PULLUP); } void loop() { @@ -29,6 +34,4 @@ void loop() { apply_pid(&g_dui_target_state, &g_dui_current_state); apply_state(&g_dui_current_state); - - delay(10); } -- cgit v1.2.3 From cef95354c69745f782a95d37f4b0e7bbf02e106a Mon Sep 17 00:00:00 2001 From: lonkaars Date: Wed, 24 May 2023 18:03:05 +0200 Subject: uart working --- nicla/serial_test.py | 19 ++++++++++--------- zumo/.gitignore | 1 - zumo/pidtest.cpp | 18 ------------------ zumo/pidtest.mk | 21 --------------------- zumo/pidtest/.gitignore | 1 + zumo/pidtest/makefile | 21 +++++++++++++++++++++ zumo/pidtest/pidtest.cpp | 18 ++++++++++++++++++ zumo/protocol.cpp | 18 +++++++++++++++++- zumo/protocol.h | 3 +++ zumo/zumo.ino | 3 --- 10 files changed, 70 insertions(+), 53 deletions(-) delete mode 100644 zumo/pidtest.cpp delete mode 100644 zumo/pidtest.mk create mode 100644 zumo/pidtest/.gitignore create mode 100644 zumo/pidtest/makefile create mode 100644 zumo/pidtest/pidtest.cpp diff --git a/nicla/serial_test.py b/nicla/serial_test.py index bef43a2..c8b84e5 100644 --- a/nicla/serial_test.py +++ b/nicla/serial_test.py @@ -1,21 +1,22 @@ -from pyb import Pin, delay +from pyb import Pin, delay, udelay zumo_tx = Pin("PA10", Pin.IN) zumo_rx = Pin("PA9", Pin.OUT_PP) -def uart_send(s): +def uart_send(byte): zumo_rx.value(0) - byte = ord(s) - print("START BIT") - delay(2) + udelay(1000) for x in range(8): bit = (byte & (1 << 7)) >> 7 byte <<= 1 zumo_rx.value(bit) - print(f"BIT[{x}] = {bit}") - delay(2) - print("STOP BIT") + udelay(1000) zumo_rx.value(1) while True: - uart_send("a") + # uart_send("a") + for x in range(8): + n = 1 << x + uart_send(n) + print(f"0x{n:02x}") + delay(1000) diff --git a/zumo/.gitignore b/zumo/.gitignore index e45f7a2..5761abc 100644 --- a/zumo/.gitignore +++ b/zumo/.gitignore @@ -1,2 +1 @@ *.o -pidtest diff --git a/zumo/pidtest.cpp b/zumo/pidtest.cpp deleted file mode 100644 index b9ce50b..0000000 --- a/zumo/pidtest.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include -#include - -#include "pid.h" - -int main() { - float P, I, D; - P = -0.02; - I = 0.13; - D = -300; - PID test(P, I, D); - test.reset(0.0); - - fprintf(stderr, "P: %.3f :: I: %.3f :: D: %.3f\n", P, I, D); - for (unsigned int i = 0; i < 100; i++) { - printf("%2.8f\n", test.iter(i < 50 ? 1.0 : 0.0)); - } -} diff --git a/zumo/pidtest.mk b/zumo/pidtest.mk deleted file mode 100644 index 5ffe1e1..0000000 --- a/zumo/pidtest.mk +++ /dev/null @@ -1,21 +0,0 @@ -CPP = g++ -LD = g++ -RM = rm -f -CFLAGS = -LFLAGS = -TARGET = pidtest - -SRCS := pidtest.cpp pid.cpp -OBJS := pidtest.o pid.o - -all: pidtest - -%.o: %.cpp - $(CPP) -c $(CFLAGS) $< -o $@ - -$(TARGET): $(OBJS) - $(LD) $^ $(LFLAGS) -o $@ - -clean: - $(RM) $(TARGET) $(OBJS) - diff --git a/zumo/pidtest/.gitignore b/zumo/pidtest/.gitignore new file mode 100644 index 0000000..41dc46e --- /dev/null +++ b/zumo/pidtest/.gitignore @@ -0,0 +1 @@ +pidtest diff --git a/zumo/pidtest/makefile b/zumo/pidtest/makefile new file mode 100644 index 0000000..832d60b --- /dev/null +++ b/zumo/pidtest/makefile @@ -0,0 +1,21 @@ +CPP = g++ +LD = g++ +RM = rm -f +CFLAGS = +LFLAGS = +TARGET = pidtest + +SRCS := pidtest.cpp ../pid.cpp +OBJS := pidtest.o ../pid.o + +all: pidtest + +%.o: %.cpp + $(CPP) -c $(CFLAGS) $< -o $@ + +$(TARGET): $(OBJS) + $(LD) $^ $(LFLAGS) -o $@ + +clean: + $(RM) $(TARGET) $(OBJS) + diff --git a/zumo/pidtest/pidtest.cpp b/zumo/pidtest/pidtest.cpp new file mode 100644 index 0000000..4d047fb --- /dev/null +++ b/zumo/pidtest/pidtest.cpp @@ -0,0 +1,18 @@ +#include +#include + +#include "../pid.h" + +int main() { + float P, I, D; + P = -0.02; + I = 0.13; + D = -300; + PID test(P, I, D); + test.reset(0.0); + + fprintf(stderr, "P: %.3f :: I: %.3f :: D: %.3f\n", P, I, D); + for (unsigned int i = 0; i < 100; i++) { + printf("%2.8f\n", test.iter(i < 50 ? 1.0 : 0.0)); + } +} diff --git a/zumo/protocol.cpp b/zumo/protocol.cpp index fea8a00..f11827c 100644 --- a/zumo/protocol.cpp +++ b/zumo/protocol.cpp @@ -1,4 +1,6 @@ #include +#include +#include #include "protocol.h" @@ -34,6 +36,20 @@ void apply_state(dui_state_t *state) { // TODO: print sign on OLED screen } +inline bool rx() { return !digitalRead(DUI_PINOUT_NICLA_RX); } + unsigned char uart_read() { - return 0x00; + if (rx() == true) return 0x00; // return immediately if line is idle + + delayMicroseconds(1500); // wait out start bit + + unsigned char byte = 0x00; + for (unsigned int i = 0; i < 8; i++) { + byte = (byte << 1) | rx(); + delayMicroseconds(1000); + } + + delayMicroseconds(1000); // wait out stop bit + + return byte; } diff --git a/zumo/protocol.h b/zumo/protocol.h index 662a5ce..9db7902 100644 --- a/zumo/protocol.h +++ b/zumo/protocol.h @@ -1,5 +1,8 @@ #pragma once +#define DUI_PINOUT_NICLA_TX 13 +#define DUI_PINOUT_NICLA_RX 14 + typedef enum { DUI_CMD_NULL, DUI_CMD_SIGN, diff --git a/zumo/zumo.ino b/zumo/zumo.ino index c65c2f9..e53513b 100644 --- a/zumo/zumo.ino +++ b/zumo/zumo.ino @@ -5,9 +5,6 @@ #include "protocol.h" #include "pid.h" -#define DUI_PINOUT_NICLA_TX 13 -#define DUI_PINOUT_NICLA_RX 14 - dui_state_t g_dui_target_state = { .steer = 1.0f, .speed = 1.0f, -- cgit v1.2.3 From d0a1cc366e1657b4d65bd5c3bef35f4173ef2b15 Mon Sep 17 00:00:00 2001 From: lonkaars Date: Wed, 24 May 2023 20:51:23 +0200 Subject: fix protocol implementation --- zumo/control.cpp | 37 +++++++++++++++++++++++++++++ zumo/control.h | 12 ++++++++++ zumo/protocol.cpp | 48 ++++++-------------------------------- zumo/protocol.h | 7 ------ zumo/protocoltest/.gitignore | 1 + zumo/protocoltest/makefile | 21 +++++++++++++++++ zumo/protocoltest/protocoltest.cpp | 35 +++++++++++++++++++++++++++ 7 files changed, 113 insertions(+), 48 deletions(-) create mode 100644 zumo/control.cpp create mode 100644 zumo/control.h create mode 100644 zumo/protocoltest/.gitignore create mode 100644 zumo/protocoltest/makefile create mode 100644 zumo/protocoltest/protocoltest.cpp diff --git a/zumo/control.cpp b/zumo/control.cpp new file mode 100644 index 0000000..263c145 --- /dev/null +++ b/zumo/control.cpp @@ -0,0 +1,37 @@ +#include +#include +#include + +#include "protocol.h" + +#define DUI_SPEED_MOD 96.0f +#define DUI_MOTOR_DIFF 0.6f + +void apply_state(dui_state_t *state) { + float motor_l = 0.5f * state->speed * (+1.f * state->steer * DUI_MOTOR_DIFF - DUI_MOTOR_DIFF + 2) * state->speed_mod * DUI_SPEED_MOD; + float motor_r = 0.5f * state->speed * (-1.f * state->steer * DUI_MOTOR_DIFF - DUI_MOTOR_DIFF + 2) * state->speed_mod * DUI_SPEED_MOD; + + Zumo32U4Motors::setLeftSpeed((int16_t) motor_l); + Zumo32U4Motors::setRightSpeed((int16_t) motor_r); + + // TODO: print sign on OLED screen +} + +inline bool rx() { return !digitalRead(DUI_PINOUT_NICLA_RX); } + +unsigned char uart_read() { + if (rx() == true) return 0x00; // return immediately if line is idle + + delayMicroseconds(1500); // wait out start bit + + unsigned char byte = 0x00; + for (unsigned int i = 0; i < 8; i++) { + byte = (byte << 1) | rx(); + delayMicroseconds(1000); + } + + delayMicroseconds(1000); // wait out stop bit + + return byte; +} + diff --git a/zumo/control.h b/zumo/control.h new file mode 100644 index 0000000..12ecbd7 --- /dev/null +++ b/zumo/control.h @@ -0,0 +1,12 @@ +#pragma once + +#include "protocol.h" + +#define DUI_PINOUT_NICLA_TX 13 +#define DUI_PINOUT_NICLA_RX 14 + +/** @brief non blocking read byte */ +unsigned char uart_read(); +/** @brief apply state to motors */ +void apply_state(dui_state_t* state); + diff --git a/zumo/protocol.cpp b/zumo/protocol.cpp index f11827c..ab8397a 100644 --- a/zumo/protocol.cpp +++ b/zumo/protocol.cpp @@ -1,55 +1,21 @@ -#include -#include -#include - #include "protocol.h" -#define DUI_SPEED_MOD 96.0f -#define DUI_MOTOR_DIFF 0.6f - #define DUI_CMD_NULL 0x00 #define DUI_CMD_SIGN_START 0x01 #define DUI_CMD_SIGN_END 0x0f -#define DUI_CMD_STEER_START 0x10 -#define DUI_CMD_STEER_END 0x1f -#define DUI_CMD_SPEED_START 0x20 -#define DUI_CMD_SPEED_END 0xff +#define DUI_CMD_SPEED_START 0x10 +#define DUI_CMD_SPEED_END 0x1f +#define DUI_CMD_STEER_START 0x20 +#define DUI_CMD_STEER_END 0xff void handle_cmd(unsigned char cmd, dui_state_t *state) { if (cmd == DUI_CMD_NULL) return; else if (DUI_CMD_SIGN_START <= cmd && cmd <= DUI_CMD_SIGN_END) { state->current_sign = (dui_e_sign) (cmd - DUI_CMD_SIGN_START); - } else if (DUI_CMD_STEER_START <= cmd && cmd <= DUI_CMD_STEER_END) { - state->steer = (float) (cmd - DUI_CMD_STEER_START) / (float) (DUI_CMD_STEER_END - DUI_CMD_STEER_START); } else if (DUI_CMD_SPEED_START <= cmd && cmd <= DUI_CMD_SPEED_END) { - state->speed = ((float) (cmd - DUI_CMD_SPEED_START) / (float) (DUI_CMD_SPEED_START - DUI_CMD_SPEED_END) * (float) 2 - (float) 1); + state->speed = (float) (cmd - DUI_CMD_SPEED_START) / (float) (DUI_CMD_SPEED_END - DUI_CMD_SPEED_START); + } else if (DUI_CMD_STEER_START <= cmd && cmd <= DUI_CMD_STEER_END) { + state->steer = (float) (cmd - DUI_CMD_STEER_START) / (float) (DUI_CMD_STEER_END - DUI_CMD_STEER_START) * (float) 2 - (float) 1; } } -void apply_state(dui_state_t *state) { - float motor_l = 0.5f * state->speed * (+1.f * state->steer * DUI_MOTOR_DIFF - DUI_MOTOR_DIFF + 2) * state->speed_mod * DUI_SPEED_MOD; - float motor_r = 0.5f * state->speed * (-1.f * state->steer * DUI_MOTOR_DIFF - DUI_MOTOR_DIFF + 2) * state->speed_mod * DUI_SPEED_MOD; - - Zumo32U4Motors::setLeftSpeed((int16_t) motor_l); - Zumo32U4Motors::setRightSpeed((int16_t) motor_r); - - // TODO: print sign on OLED screen -} - -inline bool rx() { return !digitalRead(DUI_PINOUT_NICLA_RX); } - -unsigned char uart_read() { - if (rx() == true) return 0x00; // return immediately if line is idle - - delayMicroseconds(1500); // wait out start bit - - unsigned char byte = 0x00; - for (unsigned int i = 0; i < 8; i++) { - byte = (byte << 1) | rx(); - delayMicroseconds(1000); - } - - delayMicroseconds(1000); // wait out stop bit - - return byte; -} diff --git a/zumo/protocol.h b/zumo/protocol.h index 9db7902..a1f9951 100644 --- a/zumo/protocol.h +++ b/zumo/protocol.h @@ -1,8 +1,5 @@ #pragma once -#define DUI_PINOUT_NICLA_TX 13 -#define DUI_PINOUT_NICLA_RX 14 - typedef enum { DUI_CMD_NULL, DUI_CMD_SIGN, @@ -29,10 +26,6 @@ typedef struct { float speed_mod; /** @brief global speed multiplier */ } dui_state_t; -/** @brief non blocking read byte */ -unsigned char uart_read(); /** @brief read and apply cmd to state */ void handle_cmd(unsigned char cmd, dui_state_t *state); -/** @brief apply state to motors */ -void apply_state(dui_state_t* state); diff --git a/zumo/protocoltest/.gitignore b/zumo/protocoltest/.gitignore new file mode 100644 index 0000000..fb5d35f --- /dev/null +++ b/zumo/protocoltest/.gitignore @@ -0,0 +1 @@ +protocoltest diff --git a/zumo/protocoltest/makefile b/zumo/protocoltest/makefile new file mode 100644 index 0000000..7a69352 --- /dev/null +++ b/zumo/protocoltest/makefile @@ -0,0 +1,21 @@ +CPP = g++ +LD = g++ +RM = rm -f +CFLAGS = +LFLAGS = +TARGET = protocoltest + +SRCS := $(TARGET).cpp ../protocol.cpp +OBJS := $(TARGET).o ../protocol.o + +all: $(TARGET) + +%.o: %.cpp + $(CPP) -c $(CFLAGS) $< -o $@ + +$(TARGET): $(OBJS) + $(LD) $^ $(LFLAGS) -o $@ + +clean: + $(RM) $(TARGET) $(OBJS) + diff --git a/zumo/protocoltest/protocoltest.cpp b/zumo/protocoltest/protocoltest.cpp new file mode 100644 index 0000000..461221e --- /dev/null +++ b/zumo/protocoltest/protocoltest.cpp @@ -0,0 +1,35 @@ +#include +#include + +#include "../protocol.h" + +void print_state(dui_state_t* s) { + printf("{ steer = %1.3f\n speed = %1.3f }\n", s->steer, s->speed); +} + +void test_case(unsigned char cmd, dui_state_t* s) { + printf("\ncmd in = 0x%02x\n", cmd); + handle_cmd(cmd, s); + print_state(s); +} + +int main() { + dui_state_t state = { + .steer = 0.f, + .speed = 1.f, + .current_sign = DUI_SIGN_NONE, + .speed_mod = 1.f, + }; + + test_case(0x00, &state); + test_case(0x01, &state); + test_case(0x02, &state); + test_case(0x10, &state); + test_case(0x15, &state); + test_case(0x1f, &state); + test_case(0x20, &state); + test_case(0x25, &state); + test_case(0x2f, &state); + test_case(0x88, &state); + test_case(0xff, &state); +} -- cgit v1.2.3 From f6cf3917fc7982e1bfe0aef295c5b228199d78d4 Mon Sep 17 00:00:00 2001 From: lonkaars Date: Wed, 24 May 2023 21:56:32 +0200 Subject: WIP nicla<->zumo integration --- nicla/serial_test.py | 36 ++++++++++++++++++++++++++++++------ zumo/control.cpp | 10 ++++++++-- zumo/zumo.ino | 21 +++++++++++++++------ 3 files changed, 53 insertions(+), 14 deletions(-) diff --git a/nicla/serial_test.py b/nicla/serial_test.py index c8b84e5..276f6d1 100644 --- a/nicla/serial_test.py +++ b/nicla/serial_test.py @@ -13,10 +13,34 @@ def uart_send(byte): udelay(1000) zumo_rx.value(1) -while True: - # uart_send("a") - for x in range(8): - n = 1 << x - uart_send(n) - print(f"0x{n:02x}") +__uart_buffer = bytearray() +def uart_flush(): + global __uart_buffer + print("UART FLUSH START") + for byte in __uart_buffer: + print(f"BYTE 0x{byte:02X}") + uart_send(byte) # dit is de oplossing + udelay(2000) + uart_send(byte) + udelay(2000) + uart_send(byte) + __uart_buffer = bytearray() + +def tx_irq_handler(pin): + if pin is zumo_tx: + uart_flush() + +zumo_tx.irq(trigger = Pin.IRQ_RISING, handler = tx_irq_handler) + +def uart_buffer(i): + global __uart_buffer + __uart_buffer.append(i) + +if __name__ == "__main__": + while True: # test commands + uart_buffer(0x29) + uart_buffer(0x70) + delay(1000) + uart_buffer(0xff) + uart_buffer(0x20) delay(1000) diff --git a/zumo/control.cpp b/zumo/control.cpp index 263c145..778969a 100644 --- a/zumo/control.cpp +++ b/zumo/control.cpp @@ -3,6 +3,7 @@ #include #include "protocol.h" +#include "control.h" #define DUI_SPEED_MOD 96.0f #define DUI_MOTOR_DIFF 0.6f @@ -11,6 +12,12 @@ void apply_state(dui_state_t *state) { float motor_l = 0.5f * state->speed * (+1.f * state->steer * DUI_MOTOR_DIFF - DUI_MOTOR_DIFF + 2) * state->speed_mod * DUI_SPEED_MOD; float motor_r = 0.5f * state->speed * (-1.f * state->steer * DUI_MOTOR_DIFF - DUI_MOTOR_DIFF + 2) * state->speed_mod * DUI_SPEED_MOD; + Serial.print(motor_l); + Serial.print(" "); + Serial.print(motor_r); + + Serial.println(""); + Zumo32U4Motors::setLeftSpeed((int16_t) motor_l); Zumo32U4Motors::setRightSpeed((int16_t) motor_r); @@ -22,7 +29,7 @@ inline bool rx() { return !digitalRead(DUI_PINOUT_NICLA_RX); } unsigned char uart_read() { if (rx() == true) return 0x00; // return immediately if line is idle - delayMicroseconds(1500); // wait out start bit + delayMicroseconds(1200); // wait out start bit unsigned char byte = 0x00; for (unsigned int i = 0; i < 8; i++) { @@ -34,4 +41,3 @@ unsigned char uart_read() { return byte; } - diff --git a/zumo/zumo.ino b/zumo/zumo.ino index e53513b..1a64381 100644 --- a/zumo/zumo.ino +++ b/zumo/zumo.ino @@ -2,18 +2,19 @@ #include #include +#include "control.h" #include "protocol.h" #include "pid.h" dui_state_t g_dui_target_state = { - .steer = 1.0f, - .speed = 1.0f, + .steer = 0.0f, + .speed = 0.0f, .current_sign = DUI_SIGN_NONE, .speed_mod = 1.f, }; dui_state_t g_dui_current_state = { .steer = 0.f, - .speed = 1.f, + .speed = 0.f, .current_sign = DUI_SIGN_NONE, .speed_mod = 1.f, }; @@ -21,14 +22,22 @@ dui_state_t g_dui_current_state = { void setup() { pinMode(DUI_PINOUT_NICLA_TX, OUTPUT); pinMode(DUI_PINOUT_NICLA_RX, INPUT_PULLUP); + Serial.begin(115200); } void loop() { - unsigned char cmd = 0x00; - while ((cmd = uart_read())) - handle_cmd(cmd, &g_dui_target_state); + static unsigned char cmd_old = 0x00; + for (unsigned int i = 0; i < 1000; i++) { + digitalWrite(DUI_PINOUT_NICLA_TX, LOW); + unsigned char cmd = uart_read(); + if (cmd == 0x00) continue; + if (cmd == cmd_old) handle_cmd(cmd, &g_dui_target_state); + cmd_old = cmd; + } + digitalWrite(DUI_PINOUT_NICLA_TX, HIGH); apply_pid(&g_dui_target_state, &g_dui_current_state); + g_dui_current_state.current_sign = g_dui_target_state.current_sign; apply_state(&g_dui_current_state); } -- cgit v1.2.3 From 0f764db3c3595e863a4949c67592451c7d65a2cf Mon Sep 17 00:00:00 2001 From: lonkaars Date: Mon, 5 Jun 2023 11:55:09 +0200 Subject: shaky traffic light detection in micropython --- nicla/traffic_light.py | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 nicla/traffic_light.py diff --git a/nicla/traffic_light.py b/nicla/traffic_light.py new file mode 100644 index 0000000..3d81139 --- /dev/null +++ b/nicla/traffic_light.py @@ -0,0 +1,65 @@ +import sensor, image, time, math + +sensor.reset() +sensor.set_pixformat(sensor.RGB565) +sensor.set_framesize(sensor.QVGA) +sensor.skip_frames(time = 2000) +clock = time.clock() + +""" +returns hsv tuple for rgb input tuple +""" +def rgb2hsv(rgb): + r, g, b = rgb + maxc = max(r, g, b) + minc = min(r, g, b) + rangec = (maxc-minc) + v = maxc + if minc == maxc: + return 0.0, 0.0, v + s = rangec / maxc + rc = (maxc-r) / rangec + gc = (maxc-g) / rangec + bc = (maxc-b) / rangec + if r == maxc: + h = bc-gc + elif g == maxc: + h = 2.0+rc-bc + else: + h = 4.0+gc-rc + h = (h/6.0) % 1.0 + return (h, s, v) + +while(True): + clock.tick() + img = sensor.snapshot() + ## todo: downsample img + original = img.copy(copy_to_fb=True) + img = img.to_grayscale() + for blob in img.find_blobs([(0, 60)], pixels_threshold=100): + aspect = blob.h() / blob.w() + if abs(aspect - 2.2) > 0.5: continue + lights = ( + (round(blob.x() + blob.w() / 2), round(blob.y() + 0.8 * blob.h())), + (round(blob.x() + blob.w() / 2), round(blob.y() + 0.5 * blob.h())), + (round(blob.x() + blob.w() / 2), round(blob.y() + 0.2 * blob.h())), + ) + + light_status = 0 + for i, light in enumerate(lights): + r, g, b = original.get_pixel(light[0], light[1]) + h, s, v = rgb2hsv(((r/255),(g/255),(b/255),)) + if s < 0.65: continue + # if v < 0.3: continue + if i == 0 and abs(h - 0.50) < 0.45: continue + if i == 1 and abs(h - 0.05) > 0.1: continue + if i == 2 and abs(h - 0.40) > 0.1: continue + light_status = i + 1 + print((h,s,v,)) + break + if light_status == 0: + continue + + img.draw_rectangle(blob.rect()) + img.draw_circle(lights[light_status-1][0], lights[light_status-1][1], 2) + print(("", "rood", "geel", "groen")[light_status]) -- cgit v1.2.3