Hackster is hosting Hackster Holidays, Ep. 6: Livestream & Giveaway Drawing. Watch previous episodes or stream live on Monday!Stream Hackster Holidays, Ep. 6 on Monday!
Pukhraj Dhiman
Published © LGPL

Weed Removal & Insecticides/Pesticides Sprayer Robot

Using A.I. to Detect & Remove Weeds Besides the Crop and Spray Insecticides/Pesticides at that point to stop weed from further growing.

AdvancedWork in progressOver 1 day698
Weed Removal & Insecticides/Pesticides Sprayer Robot

Things used in this project

Hardware components

NXP MR-BUGGY3-KIT
×1
RDDRONE-FMUK66
NXP RDDRONE-FMUK66
×1
NXP UCANS32K1SIC Development Board
×1
NXP HGD-Telemetry Unit 433 Mhz
×1
Google Coral Camera Module
×2
Orange 2S 7.4V 2200mah Lipo Battery
×1
PCA9685 12 Channel 12 Bit Servo Driver
×1
Generic Robotic Arm with Gripper
×1
USB Camera
×1
SG90 Micro-servo motor
SG90 Micro-servo motor
×4
Lipo Charger
×1
Female/Female Jumper Wires
Female/Female Jumper Wires
×14
Male/Female Jumper Wires
Male/Female Jumper Wires
×15
USB-A to USB-C Adaptor
×1

Software apps and online services

PX4
PX4
QGroundControl
PX4 QGroundControl
MAVLink
PX4 MAVLink
Robot Operating System
ROS Robot Operating System
TensorFlow
TensorFlow
NXP eIQ Software Toolkit
Pycharm

Hand tools and fabrication machines

Extraction Tool, 6 Piece Screw Extractor & Screwdriver Set
Extraction Tool, 6 Piece Screw Extractor & Screwdriver Set
Tape, Double Sided
Tape, Double Sided

Story

Read more

Code

Python Code for Weed Detection & Extraction using Servo Gripper connected via UCANS32K1SIC Board

Python
The Code detects the weed and send instruction via PWM signals to Gripper to extract weed
import cv2
import numpy as np
from edgetpu.classification.engine import ClassificationEngine
from pynq.lib import Pmod_PWM
from pynq.overlays.base import BaseOverlay

# Initialize the UCANS32K1SIC board and PWM pins
base = BaseOverlay("base.bit")
pwm1 = Pmod_PWM(base.PMODA, 0)
pwm2 = Pmod_PWM(base.PMODA, 1)

# Set the duty cycle and frequency for the PWM pins
pwm1.generate(50, 0.5)
pwm2.generate(50, 0.5)

# Load the Google Coral classification engine
engine = ClassificationEngine('/path/to/model.tflite')

# Open the camera and capture frames
cap = cv2.VideoCapture(0)
while True:
    ret, frame = cap.read()

    # Preprocess the frame for classification
    resized = cv2.resize(frame, (224, 224))
    resized = resized[:, :, ::-1].copy()
    input_data = np.asarray(resized, dtype=np.float32)
    input_data = np.expand_dims(input_data, axis=0)

    # Run the classification on the frame
    results = engine.classify_with_input_tensor(input_data, threshold=0.5, top_k=1)

    # Check if a weed is detected
    if results[0][0][1] == 'weed':
        # Move the servo motors to extract the weed
        pwm1.generate(50, 0.1)
        pwm2.generate(50, 0.9)

    # Display the classification results on the frame
    cv2.putText(frame, results[0][0][1], (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1,(0, 255, 0), 2, cv2.LINE_AA)
    cv2.imshow('frame', frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# Release the camera and PWM pins
cap.release()
pwm1.stop()
pwm2.stop()
cv2.destroyAllWindows()

Python Code for NAVQPlus with a connected USB Camera to follow a white line

Python
The Code helps the buggy to follow a white line drawn in parallel with the Crops and will stops whenever the RDDRONE-FMUK66 will sent an interrupt signal when the Google Coral Camera connected to NAVQPlus detects Weed.
import cv2
import numpy as np
import socket

# Set up communication with RDDRONE-FMUK66
UDP_IP = "192.168.1.1"
UDP_PORT = 8000
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

# Create a VideoCapture object for the camera
cap = cv2.VideoCapture(0)

# Check if camera is opened correctly
if not cap.isOpened():
    print("Cannot open camera")
    exit()

while True:
    # Read a frame from the camera
    ret, frame = cap.read()

    # Check if frame is captured correctly
    if not ret:
        print("Can't receive frame (stream end?). Exiting ...")
        break

    # Convert the frame to grayscale and blur it to reduce noise
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    blurred = cv2.GaussianBlur(gray, (5, 5), 0)

    # Threshold the image to create a binary image of the white line
    _, thresh = cv2.threshold(blurred, 200, 255, cv2.THRESH_BINARY)

    # Find contours in the binary image
    contours, _ = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

    # If contours are found, find the contour with the largest area
    if len(contours) > 0:
        c = max(contours, key=cv2.contourArea)

        # Find the centroid of the largest contour
        M = cv2.moments(c)
        cx = int(M['m10'] / M['m00'])
        cy = int(M['m01'] / M['m00'])

        # Draw a circle at the centroid of the largest contour
        cv2.circle(frame, (cx, cy), 5, (0, 0, 255), -1)

        # Generate commands to control the drone to follow the line
        # For example, you could use the centroid coordinates to control the drone's pitch and roll

    # Send commands to stop the drone when a signal is received from RDDRONE-FMUK66
    data, _ = sock.recvfrom(1024)
    if data == b'stop':
        break

    # Display the resulting frame
    cv2.imshow('frame', frame)
    if cv2.waitKey(1) == ord('q'):
        break

# Release the camera and close all windows
cap.release()
cv2.destroyAllWindows()

Credits

Pukhraj Dhiman

Pukhraj Dhiman

13 projects β€’ 6 followers

Comments