Kim Madsen
Published © MIT

Hailo rpi5 and pico as IO

This is a basic hailo+ hat, raspberry pi 5 and a rpi pico as IO

AdvancedFull instructions provided4 hours260
Hailo rpi5 and pico as IO

Things used in this project

Hardware components

Raspberry Pi 5
Raspberry Pi 5
8mb model
×1
Camera Module
Raspberry Pi Camera Module
wide model 3
×1
raspberry pi AI+ hat
×1
Pan-Tilt HAT
Pimoroni Pan-Tilt HAT
I am NOT using the extension board.
×1
Raspberry Pi Pico
Raspberry Pi Pico
×1

Software apps and online services

hailo-rpi5-examples
Arduino IDE
Arduino IDE

Story

Read more

Code

comport driver src.

C/C++
comport driver for the rpi pico
put it in hailopipe sub directory.
#pragma once

#include <iostream>
#include <mutex>
#include <thread>
#include <string>
#include <stdio.h>
#include <queue>
#include <chrono>


// Linux headers
#include <fcntl.h> // Contains file controls like O_RDWR
#include <errno.h> // Error integer and strerror() function
#include <termios.h> // Contains POSIX terminal control definitions
#include <unistd.h> // write(), read(), close()
#include <cstring>
#include <sys/file.h>

namespace comport {
	
	class comportACM0{
		private:
		std::string port ;
		int serial_port = 0;
		int hastighed = 0;
		bool resiverthreadrunning = false;
		std::queue<std::string> *resiverstring = new std::queue<std::string>;
		void signal_handler_IO (int status); //for initialising
		std::thread resv;
		std::mutex mtx;
		
		protected:
		
		public:
		
		comportACM0(std::string portnavn = "/dev/ttyACM0" , int speed = B115200) { //default ACM0
				this->port = portnavn;
				this->hastighed = speed;
				resv = std::thread(&comportACM0::resiverthread, this);
			}
		
		~comportACM0(void) { //default ACM0
			flock(serial_port , LOCK_UN);
			close(this->serial_port);
			delete(resiverstring);
			}

		int  resvsize(void){
				return resiverstring->size();
			}
		bool resvempty (void){
				return this->resiverstring->empty();
			}// end resvempty
		
		bool isresvrunning(void){
			return resiverthreadrunning;
			}//end isre**
			
		int hentdatalinie(std::string *data){
			if (not this->resiverstring->empty()){
				mtx.lock();
				*data = this->resiverstring->front();
				this->resiverstring->pop();
				mtx.unlock();
				}//end if
				return data->size();
			}//end hent data linie
			
		int senddatalinie(std::string *data){
			int ret = 0;
			if(serial_port > 0)
				ret = write(serial_port, data->c_str(), data->size());
			return ret;
			}//end senddata
		
		
		private:

		int portsetup(void){
				 // Open the serial port. Change device path as needed (currently set to an standard FTDI USB-UART cable type device)+
			serial_port = open(port.c_str(), O_RDWR );
			int error = flock(serial_port , LOCK_EX);
			// Create new termios struct, we call it 'tty' for convention
			std::cout << "portnavn : " << port << " Serial port : " << serial_port << std::endl;
			
			struct termios tty;
			
			// Read in existing settings, and handle any error
			if(tcgetattr(serial_port, &tty) != 0) {
					std::cerr << "Error from tcgetattr: " << errno << std::endl;
				return 1;
				}

			tty.c_cflag &= ~PARENB; // Clear parity bit, disabling parity (most common)
			tty.c_cflag &= ~CSTOPB; // Clear stop field, only one stop bit used in communication (most common)
			tty.c_cflag &= ~CSIZE; // Clear all bits that set the data size
			tty.c_cflag |= CS8; // 8 bits per byte (most common)
			tty.c_cflag &= ~CRTSCTS; // Disable RTS/CTS hardware flow control (most common)
			tty.c_cflag |= CREAD | CLOCAL; // Turn on READ & ignore ctrl lines (CLOCAL = 1)

			tty.c_lflag &= ~ICANON;
			tty.c_lflag &= ~ECHO; // Disable echo
			tty.c_lflag &= ~ECHOE; // Disable erasure
			tty.c_lflag &= ~ECHONL; // Disable new-line echo
			tty.c_lflag &= ~ISIG; // Disable interpretation of INTR, QUIT and SUSP
			tty.c_iflag &= ~(IXON | IXOFF | IXANY); // Turn off s/w flow ctrl
			tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL); // Disable any special handling of received bytes

			tty.c_oflag &= ~OPOST; // Prevent special interpretation of output bytes (e.g. newline chars)	
			tty.c_oflag &= ~ONLCR; // Prevent conversion of newline to carriage return/line feed
			// tty.c_oflag &= ~OXTABS; // Prevent conversion of tabs to spaces (NOT PRESENT ON LINUX)
			// tty.c_oflag &= ~ONOEOT; // Prevent removal of C-d chars (0x004) in output (NOT PRESENT ON LINUX)

			tty.c_cc[VTIME] = 10;    // Wait for up to 1s (10 deciseconds), returning as soon as any data is received.
			tty.c_cc[VMIN] = 0;

			// Set in/out baud rate to be 115200
			cfsetspeed(&tty, B115200);
			//cfsetospeed(&tty, B115200);
			//resv= std::thread([this]() { resiverthread(); });
			//resv = std::thread(&comportACM0::resiverthread, this);
			// Save tty settings, also checking for error
			if (tcsetattr(serial_port, TCSANOW, &tty) != 0) {
				std::cerr << "Error from tcsetattr: " << errno << std::endl;
				return 1;
				}
			return 0;

			}

		void resiverthread()
		{
				if(portsetup() == 0)
					this->resiverthreadrunning = true;			
				char buffer ;
				std::string modtagerlinie = "";
				int modtaget = 0;
				while(modtaget >= 0){
					//int num_bytes = read(serial_port, &read_buf, sizeof(read_buf));
					modtaget = read(this->serial_port , &buffer , 1);
					if(modtaget > 0){
						modtagerlinie += buffer;
						//std::cout << buffer;
						if(buffer == '\n'){
							mtx.lock();
							this->resiverstring->push(modtagerlinie);
							mtx.unlock();
							modtagerlinie = "";
							}//end if
						  }//end if
					}//end while
				std::cout << "Error reading: " << errno << " \nResiver thread stopper " << std::endl;
			}

		};
	}

new detection.py

Python
Sending text stream to hailopipe program
put it in the hailo-rpi5-examples/basic_pipelines directory
import gi
gi.require_version('Gst', '1.0')
from gi.repository import Gst, GLib
import os
import numpy as np
import cv2
import hailo
import sys

from hailo_apps_infra.hailo_rpi_common import (
    get_caps_from_pad,
    get_numpy_from_buffer,
    app_callback_class,
)
from hailo_apps_infra.detection_pipeline import GStreamerDetectionApp

# -----------------------------------------------------------------------------------------------
# User-defined class to be used in the callback function
# -----------------------------------------------------------------------------------------------
# Inheritance from the app_callback_class
class user_app_callback_class(app_callback_class):
    def __init__(self):
        super().__init__()
        self.new_variable = 42  # New variable example

    def new_function(self):  # New function example
        return "The meaning of life is: "

# -----------------------------------------------------------------------------------------------
# User-defined callback function
# -----------------------------------------------------------------------------------------------

# This is the callback function that will be called when data is available from the pipeline
def app_callback(pad, info, user_data):
    # Get the GstBuffer from the probe info
    buffer = info.get_buffer()
    # Check if the buffer is valid
    if buffer is None:
        return Gst.PadProbeReturn.OK

    # Using the user_data to count the number of frames
    user_data.increment()
    #user_data.use_frame = True
    string_to_print = f"Frame count: {user_data.get_count()} "
    # Get the caps from the pad
    format, width, height = get_caps_from_pad(pad)
    string_to_print += f"Width: {width} Heigth: {height}\n"
    # If the user_data.use_frame is set to True, we can get the video frame from the buffer
    frame = None
    label = None
    if user_data.use_frame and format is not None and width is not None and height is not None:
        # Get video frame
        frame = get_numpy_from_buffer(buffer, format, width, height)
        #string_to_print += " frame ok "
    # Get the detections from the buffer
    roi = hailo.get_roi_from_buffer(buffer)
    detections = roi.get_objects_typed(hailo.HAILO_DETECTION)

    # Parse the detections
    detection_count = 0
    for detection in detections:
        detection_count += 1
        label = detection.get_label()
        if label != None:
            bbox = detection.get_bbox()
            confidence = detection.get_confidence()
            # Get track ID
            track_id = 0
        
            track = detection.get_objects_typed(hailo.HAILO_UNIQUE_ID)
            if len(track) == 1:
                track_id = track[0].get_id()
            string_to_print += (f"Label: {label} ID: {track_id} Confidence: {confidence:.2f} Detection count: {detection_count} ")
            
            bbox = detection.get_bbox()
            
            # Call the coordinate methods
            x_min = bbox.xmin()
            y_min = bbox.ymin()
            box_width = bbox.width()
            box_height = bbox.height()
            
            # Calculate max coordinates
            x_max = x_min + box_width
            y_max = y_min + box_height
            
            # Calculate center point (these are normalized 0-1)
            center_x = x_min + (box_width / 2)
            center_y = (y_min + (box_height / 2) - 0.22) * 1.83
        
            # Debug print for coordinates
            string_to_print += (f"Position: center=({center_x:.4f}, {center_y:.4f}) "
                               f"Bounds: xmin={x_min:.4f}, ymin={y_min:.4f}, xmax={x_max:.4f}, ymax={y_max:.4f}\n")
            if user_data.use_frame:
                cv2.rectangle(frame, ((int)(x_min * width),(int) (y_min* height)), ((int)(x_max * width),(int) (y_max * height)), (255, 255, 255),1)
                cv2.putText(frame, label,((int)(x_min * width),(int) ((y_min* height) - 10)), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 1)
    
    if user_data.use_frame:
        cv2.putText(frame,f"Frame count: {user_data.get_count()}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
        
    if user_data.use_frame and label != None:
        # Note: using imshow will not work here, as the callback function is not running in the main thread
        # Let's print the detection count to the frame
        cv2.putText(frame, f"Label: {label} ID: {track_id} Confidence: {confidence:.2f} Detection count: {detection_count}", (10, 70), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
        # Example of how to use the new_variable and new_function from the user_data
        # Let's print the new_variable and the result of the new_function to the frame
        #cv2.putText(frame, f"{user_data.new_function()} {user_data.new_variable}", (10, 60), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
        # Convert the frame to BGR
        frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
        user_data.set_frame(frame)
    elif user_data.use_frame :
         frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
         user_data.set_frame(frame)
    print(string_to_print)
    sys.stdout.flush()
    return Gst.PadProbeReturn.OK

if __name__ == "__main__":
    # Create an instance of the user app callback class
    user_data = user_app_callback_class()
    app = GStreamerDetectionApp(app_callback, user_data)
    app.run()

hailopipe

C/C++
it is taking the text from the madsen.py via a named pipe /tmp/hailo
make a sub directory named hailopipe and put hailopipe.cpp in it.
void label_do_something(void) is run for every detection.
void new_frame(void) is run for every new frame.
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/stat.h>

//c++
#include <chrono>
#include <iostream>
#include <cstdio>
#include "comport.cpp"
#include <climits>
//#include <bits/stdc++.h>

#define max_count 10

namespace hailofifo {
    
    class hailofifo{
    private:
    std::string pipename = "", label = "";
    int pipeindifier = -1 , id = -1 , countnumber = 0;
    comport::comportACM0 *cport;
    std::thread piperead;
    bool pipethreadisrunning = false;
    std::mutex mtx;
    bool runmode = true , labeldetekt = false ,newframe = false, trackperson = true;
    ulong framecount = 0;
    int width = 0 , heigth = 0;    
    float confidence = 0.0 , center_x = 0.0 , center_y = 0.0 , xmin = 0.0 , ymin = 0.0 , xmax = 0.0 , ymax = 0.0;
    int person_count = 0;
    bool light_on = false , person_label = false;
    std::queue<std::string> *resiverstrings = new std::queue<std::string>;
    int person_track_id = INT_MAX;
    float person_track_x , person_track_y , person_track_xmax , person_track_ymax;
    bool person_track_detect = false;
    
    void init(void){
        int unlink((const char )*this->pipename.c_str());
        mkfifo(this->pipename.c_str(), 0666);
        this->pipeindifier = open(this->pipename.c_str(), O_RDONLY);
        }//end init
    
    void pipereadthread( void) {
        mtx.lock();
        this->pipethreadisrunning = true;
        mtx.unlock();
        char buffer = 0;
        std::string resiverline = "";
        int readnumber = 0;
        
        while(pipeindifier >=0){
            readnumber =read(pipeindifier, &buffer, sizeof(buffer));
            if(readnumber > 0){
                    resiverline += buffer;
                    if(buffer == '\n'){
                        mtx.lock();
                        resiverstrings->push(resiverline);
                        mtx.unlock();
                        resiverline = "";
                        }//end if
                }else {
                     std::this_thread::sleep_for(std::chrono::microseconds(10));
                    }//end if
            }//end while
        }//end piperead thread
        
      void detection_string(void){
            mtx.lock();
            std::string resvtxt = resiverstrings->front();
            resiverstrings->pop();
            mtx.unlock();
            //std::cout << resvtxt  ;
            std::string substring = "Frame count:";
            int found = resvtxt.find(substring);
            if(found == 0){
                newframe = true; 
                int from = substring.size() + 1;
                substring = "Width:";
                found = resvtxt.find(substring ,from);
                std::string number = resvtxt.substr(from , found - 1 );
                this->framecount = std::stoi(number);
                from  = found + substring.size() + 1;
                substring = "Heigth:";
                found = resvtxt.find(substring , from);
                number = resvtxt.substr(from , found - 1 );
                this->width = std::stoi(number);
                from  = found + substring.size() + 1;
                number = resvtxt.substr(from , resvtxt.size()-1);
                this->heigth = std::stoi(number);
                //std::cout << "Framenumber : " << this->framecount << " width : " << this->width << " heigth : " << this->heigth << std::endl;
                }else{
                    substring = "Label:";
                    found = resvtxt.find(substring);
                    int from = substring.size() + 1;
                    if(found == 0){
                        labeldetekt = true;
                        from = substring.size() + 1;
                        substring = "ID:";
                        found = resvtxt.find(substring );
                        this->label = resvtxt.substr(from , (found - 1) - from );
                        from  = found + substring.size() + 1;
                        substring = "Confidence:";
                        found = resvtxt.find(substring , from);
                        std::string number = resvtxt.substr(from , found - 1 );
                        this->id = std::stoi(number);
                        from  = found + substring.size() + 1;
                        substring = "Detection count:";
                        found = resvtxt.find(substring, from);
                        number = resvtxt.substr(from , found - 1 );
                        this->confidence = std::stof(number);
                        from  = found + substring.size() + 1;
                        substring = "Position:";
                        found = resvtxt.find(substring , from);
                        number = resvtxt.substr(from , found - 1 );
                        this->countnumber = std::stoi(number);
                        substring = "center=(";
                        found = resvtxt.find(substring , from);
                        from  = found + substring.size() + 1;
                        substring = ",";
                        found = resvtxt.find(substring , from);
                        number = resvtxt.substr(from , found - 1 );
                        this->center_x = std::stof(number);
                        from = found + 1;
                        substring = ")";
                        found = resvtxt.find(substring , from);
                        number = resvtxt.substr(from , found - 1 );
                        this->center_y = std::stof(number);
                        from = found+1;
                        substring = "xmin=";
                        found = resvtxt.find(substring , from);
                        from = found + substring.size();
                        substring = ",";
                        found = resvtxt.find(substring , from);
                        number = resvtxt.substr(from , found - 1 );
                        this->xmin = std::stof(number);
                        from = found+1;
                        substring = "ymin=";
                        found = resvtxt.find(substring , from);
                        from = found + substring.size();
                        substring = ",";
                        found = resvtxt.find(substring , from);
                        number = resvtxt.substr(from , found - 1 );
                        this->ymin = std::stof(number);
                        from = found+1;
                        substring = "xmax=";
                        found = resvtxt.find(substring , from);
                        from = found + substring.size();
                        substring = ",";
                        found = resvtxt.find(substring , from);
                        number = resvtxt.substr(from , found - 1 );
                        this->xmax = std::stof(number);
                        from = found+1;
                        substring = "ymax=";
                        found = resvtxt.find(substring , from);
                        from = found + substring.size();
                        number = resvtxt.substr(from , resvtxt.size());
                        this->ymax = std::stof(number);
                        //std::cout << "label : " << this->label << " id : " << this->id << " conf : " << this->confidence << " Detection count number : " << this->countnumber << " center x : " << this->center_x << " center y : " << this->center_y << " xmin : " << this->xmin << " ymin : " << this->ymin << " xmax : " << this->xmax << " ymax : " << this->ymax << std::endl << std::endl;
                        } else {
                            substring = "Shutting down...";
                            found = resvtxt.find(substring);
                            if(found == 0){
                                runmode = false; //quit
                                std::cout <<"\nend of program \n";
                                return; // end of program
                                }//end if
                            }//end if
                    }//end if
          } 

    
    void label_do_something(void){
        labeldetekt = false;
        std::string detval = "person";
        if(this->label == detval){
            person_label = true;
            if(this->trackperson ){
                 if(this->person_track_id >= this->id){
                        this->person_track_detect = true;
                        this->person_track_x = this->center_x;
                        this->person_track_y = this->center_y ;
                        this->person_track_xmax = this->xmax - this->xmin;
                        this->person_track_ymax = this->ymax - this->ymin;
                     }//end if
                }//end if
            }//end if
        }//end label_do_something
    
    void new_frame(void){
            std::string datatxt = "";
            newframe = false;
            //std::cout << "frame number : " << this->framecount << std::endl; 
            if(person_label){ 
                person_label = false;
                if(this->person_count < max_count and this->confidence > 0.40){
                    ++this->person_count;
                }else{
                    if(this->person_count > 0)
                        person_count--;
                    }//end if
                if(this->person_count == max_count){
                    if(this->light_on == false){
                        std::cout << "light on" << std::endl;
                        datatxt = "light on \n";
                        cport->senddatalinie(&datatxt);
                        this->light_on = true;
                        std::cout << "person detected \n";
                        }//  end if
                } //end if
            if(this->person_track_detect){
                    datatxt = "Track:";
                    datatxt += "Width:";
                    datatxt += std::to_string(this->width);
                    datatxt += "Heigth:";
                    datatxt += std::to_string(this->heigth);
                    datatxt += "cx:";
                    datatxt += std::to_string(this->person_track_x);
                    datatxt += "cy:";
                    datatxt += std::to_string(this->person_track_y );
                    datatxt += "bx:";
                    datatxt +=std::to_string(this->person_track_xmax);
                    datatxt += "by:";
                    datatxt += std::to_string(this->person_track_ymax);
                    datatxt += "\n";
                    cport->senddatalinie(&datatxt);
                    //std::cout << datatxt;
                    }//end if
            }else{
                    if(this->person_count > 0)
                        person_count--;
                    }//end if
        //std::cout << "Person Count : " << person_count << std::endl;
        if(person_count == 0 and light_on == true){
           std::cout << "light off" << std::endl;
           datatxt = "light off\n";
           cport->senddatalinie(&datatxt);
           this->light_on = false;
            std::cout << "person NOT detected \n";
          }//end if
        this->person_track_detect = false;
        int person_track_id = INT_MAX;
        }//end new_frame    
        
    void resetcam(void){
         std::string txt =("reset  \n"); 
         cport->senddatalinie(&txt);
        }//end reset
        
    public:    
    
    hailofifo(std::string pipe = "/tmp/hailo")
    {
        this->pipename = pipe;
        //this->cport = new comport::comportACM0((std::string) "/dev/ttyACM1" , (int) B115200);
        this->cport = new comport::comportACM0; // default /dev/ttyacm0 B115200
        init();
        if(pipeindifier != -1){
            piperead = std::thread(&hailofifo::pipereadthread, this);
        }else runmode = false; //quit
      }//end hailofifo
        
    ~hailofifo()
    {
        delete cport;
        delete resiverstrings;
        int unlink((const char )*this->pipename.c_str());
        }//end destructor

    void run(void){
        resetcam();
        if(pipeindifier == -1) runmode = false;
        while(this->runmode == true){
                while(not resiverstrings->empty()){
                    detection_string();
                    if(newframe){
                            new_frame();
                        } else if(labeldetekt){
                                    label_do_something();
                                }//end if
                    if(not cport->resvempty()){
                        std::string txt = "";
                        cport->hentdatalinie(&txt);
                        //std::cout << "frame number : " << this->framecount << std::endl; 
                        std::cout << "Comport : " << txt;
                        }//end if
                    }//end while
                std::this_thread::sleep_for(std::chrono::microseconds(10));
            }//end while
        }//end run
    };//end class

}

int main() {
    //hailofifo::hailofifo *hailo = new hailofifo::hailofifo("./hailo");//new pipename
	hailofifo::hailofifo *hailo = new hailofifo::hailofifo();
    hailo->run();
  
    return 0;
}

cmakelist

ActionScript
build cmake file put it in hailopipe sub directory
set(CMAKE_CXX_STANDARD 11) is equal to opencv
cmake_minimum_required(VERSION 2.8)
project(hailopipe)

set(CMAKE_CXX_STANDARD 11)

add_executable( hailopipe hailopipe.cpp )
target_link_libraries( hailopipe )

Pico driver

C/C++
This is the driver code for the raspberry pi pico
put it in your normal arduino chain compile it and program the pico.
install 107-Arduino-Servo-RP2040 it can be found in the libary installer.
install SimpelTimer from https://github.com/jfturcot/SimpleTimer
 #include <queue>
#include <string>
#include <SimpleTimer.h>
#include <107-Arduino-Servo-RP2040.h>

#define maxposx 2000
#define maxposy 2000
#define minposx 1000
#define minposy 1700
#define timertimeout 30 
#define maxresetframecount 30

static _107_::Servo servo_0, servo_1;
SimpleTimer simpeltimer;
int autoreset = 0; //counter for autoreset

class hailotxt{
 
    private:
      int width = 0 , height = 0 , track_posx = 0 , track_posy = 0, newposx = 0 , newposy = 0;
      float cx = 0.0 , cy = 0.0;
      bool newpos = false ;
      
      int do_hailotrack(std::string *txt){
        std::string mysubstring = "Width:";
        int found = txt->find(mysubstring);
        if(found != std::string::npos){
            int from = found + mysubstring.size();
            std::string mysubstring = "Heigth:";
            found = txt->find(mysubstring ,from);
            std::string number = txt->substr(from , found - 1 );
            this->width = std::stoi(number);
            from = found + mysubstring.size();
            mysubstring = "cx:";
            found = txt->find(mysubstring ,from);
            number = txt->substr(from , found - 1 );
            this->height = std::stoi(number);
            from = found + mysubstring.size() + 1;
            mysubstring = "cy:";
            found = txt->find(mysubstring ,from);
            number = txt->substr(from , found - 1 );
            this->cx = std::stof(number);
            from = found + mysubstring.size() + 1;
            mysubstring = "bx:";
            found = txt->find(mysubstring ,from);
            number = txt->substr(from , found - 1 );
            this->cy = std::stof(number);
            track_posx = cx * width;
            track_posy = cy * height;
            int hwidth = width / 2 , hheight = height / 2;
            newposx = track_posx - hwidth;
            newposy = track_posy - hheight;
            newpos = true;
            //Serial.println("Ok");           
            return 0;
          }//end if
        return -1;
        }//end do_ha..
        
    public:
     
     hailotxt(void){}
    //return -1 if nothing done
     bool lost_track = false;
     
     int dohailotxt(std::string *txt){
      if(txt->find("Track:") != std::string::npos){
          this->do_hailotrack(txt);
          return 0;
        }//end if
      if(txt->find("light on") != std::string::npos){
          digitalWrite(LED_BUILTIN , 1);
          Serial.println("Ok");
          return 0;
        }//end if
      if(txt->find("light off") != std::string::npos){
          digitalWrite(LED_BUILTIN , 0);
          Serial.println("Ok");
          lost_track = true;
          return 0;
        }//end if
      if (txt->find("reset") != std::string::npos){
          lost_track = true; 
          Serial.println("Ok");
          Serial.println("Reset");
          return 0;
        }//end if
     
        return -1;
      }//end dohailotxt

     bool newposready(void){
        return(newpos);
      }//end newposready
      
     void getnewpos(int *x , int *y){   
      *x = newposx;
      *y = newposy;
      newpos = false;
      }// end getnewpos
  }; //end hailotxt

 void timerint (void){
    ++autoreset;   
   }//end timer int

hailotxt *hailo = new hailotxt();
int servox = 1500 , servoy = 1900;
 
void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  pinMode(LED_BUILTIN , OUTPUT);
  digitalWrite(LED_BUILTIN , LOW);
  servo_0.attach(2);
  servo_1.attach(3);
  simpeltimer.setInterval(timertimeout, timerint);
  servo_0.writeMicroseconds(servox);
  servo_1.writeMicroseconds(servoy);
}

int testnr = 0;
std::string buffer = "";
std::queue<std::string> *resiverstring = new std::queue<std::string>;

void readchar(void){
  char karakter;
  while(Serial.available() > 0){
     karakter = Serial.read();
     buffer += karakter;
     if(karakter == '\n'){
        resiverstring->push(buffer);
        buffer = "";
      }//end if
    }//end while  
  }//end readchar


void loop() {
    simpeltimer.run();
  // put your main code here, to run repeatedly:
    if(Serial.available())
      readchar();
    while(not resiverstring->empty()){
        std::string str = resiverstring->front();
        resiverstring->pop();
        hailo->dohailotxt(&str);
      }//end while
    if(hailo->newposready()){
      int x , y;
        autoreset = 0; //autoreset
        hailo->getnewpos(&x , &y);
        servox += x /15;
        servoy += y /15;
        if(servox < minposx )
          servox = minposx;
        if(servox > maxposx)
          servox = maxposx;
        if(servoy < minposy )
          servoy = minposy;
        if(servoy > maxposy)
          servoy = maxposy;
        std::string serialout = "servox = ";
        serialout += std::to_string(servox);
        serialout += " servoy = ";
        serialout += std::to_string(servoy);
        serialout += "\n";
        //Serial.print(serialout.c_str());
        servo_0.writeMicroseconds(servox);
        servo_1.writeMicroseconds(servoy);
      }//end if
      if(hailo->lost_track or autoreset > maxresetframecount){
        autoreset = 0;//autoreset
        servox = 1500;
        servoy = 1900;
        hailo->lost_track = false;
        servo_0.writeMicroseconds(servox);
        servo_1.writeMicroseconds(servoy);
        //Serial.println("lost track or autoreset");
        }//end if
   delay(1);                       // waits 15ms for the servo to reach the position
}

script file to start the chain

ActionScript
start hailo detection and the hailopipe program
put it in the hailo-rpi5-examples directory
#!/bin/bash
. setup_env.sh 
hailopipe/hailopipe &
python3 basic_pipelines/madsen.py --hef-path resources/yolov11s.hef --input rpi --show-fps >> /tmp/hailo 
#python3 basic_pipelines/madsen.py --hef-path resources/madsenstx.hef --input rpi --labels-json resources/madsen.json >>/tmp/hailo
rm /tmp/hailo

Credits

Kim Madsen
3 projects • 0 followers

Comments