acredsfan / autonomous_mower

Raspberry Pi Powered Autonomous Lawn Mower - WIP
7 stars 3 forks source link

Observations and Advice #3

Open TCIII opened 2 months ago

TCIII commented 2 months ago

Hi acredsfan, Having been working on a prototype autonomous robotic lawnmower myself, I thought that I might offer some observations and advice based on what I have learned working on my prototype.

Here is a link to my prototype robotic lawnmower. I have since encased the control module in a waterproof box. The SBC is a Raspberry Pi 4B 4GB (RPi 4B) running the Bullseye 64 bit OS and has a Robo HAT MM1 HAT attached to it that provides RC PWM signals decoding and encoding and communicates with the RPi 4B over the serial UART. The RPi 4B is presently running the Donkey Car path_follow.py template with RTK GPS to determine its lat and lon coordinates. The path_follow template webui is quite primitive when it comes to mapping an area to be mowed compared to your webi ui interface. You might want to take a look at the Donkey Car GPS part to see how RTK GPS input/output is handled by the path_follow template.

Your link to the NEO-8M is broken and the NEO-8M is somewhat dated. I suggest that you move up to the Ublox NEO-M9N.

You will notice that I wrote "RTK GPS" as normal GPS is not sufficiently accurate for providing the lat and lon accuracy required for an autonomous robotic lawnmower. Here are my two approaches to using RTK GPS, which is not cheap compared to normal GPS, but has come down in cost to the point that hobbyists can employ it in autonomous robotic designs: 1) Using the Donkey Car Path_Follow Template with RTK GPS 2) Towards an affordable Base Station for outdoor RTK GPS RC Car racing

I am also using a Pixhawk 6x mini in my other autonomous robotic lawnmower control module. Using ArduRover software on the Pixhawk 6x mini allows me to use the Mission Planner webui and accurately map an area to be mowed.

I don't believe you stated what Pi OS you are using? Both the Bullseye and Bookworm OSs use picmaera2. However your requriements.txt is loading picamera so I assume that you are using a legacy camera? I don't think that picam will work with either the Bullseye OS or the Bookworm OS. Additionally, you might want to move up to the Pi Camera v2 (IMX219) in place of the v1 (OV5647) camera. Please define your "SingletonCamera".

Do you have a schematic diagram available for this design as I can't seem to find one.

Due to all of the components that require I2C communication, you might want to recommend using a I2C Bus Splitter. The compass module should be as far from the motor magnetic fields as possible. Do you have a calibration procedure for both the compass and the IMU?

However, I like your approach using the Raspberry Pi Family of SBCs and have recently put together a CM4 4GB Lite/CM4 IO Board that is running the Bookworm 64 bit OS on a NVMe SSD and would like to support your code development effort.

Regards, TCIII

acredsfan commented 2 months ago

Hi TCIII,

Sorry for the delay in responding, I somehow missed the notification that you'd posted here. The requirements.txt may be outdated, I've made some changes to hardware including using a Pi Camera V2. I appreciate your advice, I came into this with little robotics experience so there is a ton of refinement required. I was using an I2C multiplexer but was having issues with the ToF sensors when using it. I'm currently considering using ROS2 for future development of this project but still trying to research. I'm definitely looking into the GPS module you've suggested as the N8M's accuracy is sub optimal for this application.

All your input is very much appreciated, I'll keep a better eye here moving forward!

Thank you!

TCIII commented 2 months ago

@acredsfan,

Thanks for getting back to me, much appreciated.

As you can see I have authored several blog posts on building an autonomous robotic lawnmower and how to use RTK GPS with a portable Base Station.

There is a very extensive thread on building an autonomous robotic lawnmower on the ArduPilot ArduRover sub forum that you might be interested in. As I stated before, I have built an autonomous robotic lawnmower control module that use a Pixhawk 6x mini flight controller and RTK GPS along with ArduRover and Mission Planner to created a highly accurate mower. However, I would prefer to support your efforts to use the RPi family of SBCs, RTK GPS, the Pi OSs and Python to create a an affordable and highly accurate autonomous robotic mower.

I have experimented with ROS, but very few, if any, autonomous robotic lawnmower projects use ROS and I believe that ROS is overkill for your project.

Your Python code looks very good and I suggest that you continue to improve it by integrating the RTK GPS Donkey Car gps.py part into your existing code. The Donkey Car gps.py part will work with either a standard GPS module like the NEO-M9N or a RTK GPS module like this Nav Spark RTK GPS Evaluation module.

My present RPi SBC autonomous robotic lawnmower control module uses a RPi 4B 4GB and a Robo HAT MM1 that controls a Cytron RC input differential steering motor controller. The RPi 4B is running the Donkey Car path_follow.py template that has a very primitive webui compared to your user interface. The path_follow.py template is really designed for RTK GPS autonomous RC Car racing and that is why I am really interested in your approach using Python and not ROS.

By the way, do you have a schematic diagram of how the sensor components are interconnected?

Regards, TCIII

acredsfan commented 2 months ago

This is great, I'll get caught up on your blog posts and links you've shared over the next few days. As far as a schematic (and sorry I glossed over that in the first reply) I started with this fritzing schematic from Ulli_Pi at this link. I've changed some components and wiring, but I haven't created an updated schematic yet, I'll try to get around to that soon.

TCIII commented 2 months ago

@acredsfan,

Thanks for the response. I will take a look at your schematic link this weekend. I am a retired Electrical/System Engineer so I have plenty of time on my hands to help you out.

Regards, TCIII

acredsfan commented 2 months ago

@TCIII ,

I am really excited that you've taken an interest in my project. I'm a Sr. Financial Analyst in the EV Charging Infrastrucutre space by trade, so this was a project I took on with very little working knowlege outside of basic python and having tinkered with electrical circuits. I would love your input on this mower and would be happy to add you as a collaborator on the repository if you'd be interested.

Unfortunately, my bandwidth to work on this project had diminished in the past months due to the birth of my second child and work commitments, but I'm going to be spending more time on this moving forward. Ironically, my diminished bandwidth also would have been greatly helped by having this project completed.

Thanks, acredsfan

TCIII commented 2 months ago

@acredsfan,

Fully understand as Family comes first. I will be glad to help in any way that I can from circuit analysis to software/hardware testing.

Regards, TCIII

TCIII commented 2 months ago

@acredsfan, Question: You appear to be using a TCA9548A I2C Multiplexer as it appears in your sensor_interface.py code, but not in the linked schematic nor in your parts list.

acredsfan commented 2 months ago

Let me check the robot again, I may have added it back in before I had to stop working on it so my memory is a little fuzzy. I'll get back to you momentarily.

On Fri, May 3, 2024 at 2:28 PM TCIII @.***> wrote:

@acredsfan https://github.com/acredsfan, Question: You appear to be using a TCA9548A I2C Multiplexer as it appears in your sensor_interface.py code, but not in the linked schematic nor in your parts list.

— Reply to this email directly, view it on GitHub https://github.com/acredsfan/autonomous_mower/issues/3#issuecomment-2093545177, or unsubscribe https://github.com/notifications/unsubscribe-auth/APSMOXW2ZUKPQWTGDDIKJWTZAPJLNAVCNFSM6AAAAABG4A3CESVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDAOJTGU2DKMJXG4 . You are receiving this because you were mentioned.Message ID: @.***>

acredsfan commented 2 months ago

Yes, I did add it back in at some point. I have the SDA/SCL on GPIO 2/3 on the RPI. I've removed the Relay Module and now have the wheel motors running off of 2 IBT-2 controllers and the Blade motor on a IBT-4 controller. So, I guess this makes a lot of the schematic obsolete. I found the L298N controllers to be unreliable.

TCIII commented 2 months ago

@acredsfan It is interesting that you have had issues with the L298N motor controllers as I am using two of them to drive two 12vdc brushed motors each in a NVIDIA Jetbot chassis without any issues.

I do have two IBT-2 controllers that are driving two 12vdc motors each on a Servo City 4WD chassis and those work fine also. I am using a PCA9865 servo control module operating through an Arduino Pro Micro Atmega32U4 that converts steering and throttle PWM signals into the IN1, IN2, and ENABLE signals for the two IBT-2s. This reduces the number of GPIO bus pins required to control the IBT-2s to just those required for communicating with the PCA9685 over the existing I2C Bus.

So I still don't understand the need for the I2C multiplexer other than a lack of pins on the GPIO Bus? Each sensor should have a unique I2C hex address or can be made unique when using two sensors of the same kind like the TOF modules.

Regards, TCIII

acredsfan commented 2 months ago

They may have been bad from the start but I wasn't able to get the wheels to operate consistently with the L298Ns that I purchased. The output voltage was not consistent.

Also, if I remember correctly, I used the multiplexer mainly to due to the ToF sensor package I was using. I was struggling to find one that worked with 2 sensors at the same time without the multiplexer. I'm all for removing it if there is a better package to use.

I also ordered the N9M module so thank you again for that suggestion.

On Fri, May 3, 2024, 7:01 PM TCIII @.***> wrote:

@acredsfan https://github.com/acredsfan It is interesting that you have had issues with the L298N motor controllers as I am using two of them to drive two 12vdc brushed motors each in a NVIDIA Jetbot chassis without any issues.

I do have two IBT-2 controllers that are driving two 12vdc motors each on a Servo City 4WD chassis and those work fine also. I am using a PCA9865 servo control module operating through an Arduino Pro Micro Atmega32U4 that converts steering and throttle PWM signals into the IN1, IN2, and ENABLE signals for the two IBT-2s. This reduces the number of GPIO bus pins required to control the IBT-2s to just those required for communicating with the PCA9685 over the existing I2C Bus.

So I still don't understand the need for the I2C multiplexer other than a lack of pins on the GPIO Bus? Each sensor should have a unique I2C hex address or can be made unique when using two sensors of the same kind like the TOF modules.

Regards, TCIII

— Reply to this email directly, view it on GitHub https://github.com/acredsfan/autonomous_mower/issues/3#issuecomment-2093865949, or unsubscribe https://github.com/notifications/unsubscribe-auth/APSMOXTRNNCKT26XUB4S5FDZAQJLZAVCNFSM6AAAAABG4A3CESVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDAOJTHA3DKOJUHE . You are receiving this because you were mentioned.Message ID: @.***>

TCIII commented 1 month ago

@acredsfan, You do know that you can change the I2C hex address of the TOF sensor so that each one can be read sequentially without the need of a I2C Mux? Additionally, here is a link plus this one to C++ programs that can read each TOF sequentially and I am sure it can be converted to Python code.

The Traxxas E-Maxx 4WD Truck Chassis seen in my first blog post originally used a NEO-M9N when I was using the DC path_follow.py template and could randomly veer as much as two feet out from the recorded path, depending on atmospherics and the time of day, which is not satisfactory performance for an autonomous robotic lawnmower. Switching to a RTK GPS Rover on the Truck Chassis that communicates with a stationary Base Station brought the path tracking error down to less than two inches.

Additionally, having the compass on the MPU9250 near any sizeable pieces of steel or rotating magnetic fields (motors) will make its heading output highly suspect at any given instance. Also, the MPU9250 is at EOL and has been surpassed by newer IMUs like the Bosch BNO055. You get what you pay for in the way of IMUs.

Regards, TCIII

acredsfan commented 1 month ago

I did have it set up to assign a different I2C address in a previous version of this project but I'm not sure if it was a change in Python version or something else that caused that method to stop working for me. I haven't ventured into converting C++ to Python yet but I had considered it for this and other issues.

On the GPS, those are impressive improvements. I was headed down a path of trying to combine the sensor data with OpenCV to try to get acceptable variances but that is less than ideal. The RTK GPS option would be great although, as you've pointed out, fairly costly comparatively if a base station is needed. In my area, I may be able to tap into an open RTK network provided by the DOT but if that doesn't work I'll build a base station like you outlined in your blog. These are definitely worthwhile investments in my view.

As far as the IMU, I haven't been able to verify how much interference there is but I was skeptical of how accurate it would be. So you suggest replacing it with the BNO055? For the minor cost difference I'm definitely open to it.

TCIII commented 1 month ago

@acredsfan,

Yes, you can use a NTRIP server in place of a Base Station. Ideally the location of the NTRIP server should be within 10km of where you are operating. Here is a link to using a NTRIP server with the RPi. It does require a cell phone to be working with the RPi for NTRIP server communication.

I noticed that you are using the gpsd app to acquire lat and lon from the GPS. I assume that you are reading and using the gpsd ais_messages as it does not output NMEA messages. It is interesting that you are using a Kalman Filter to massage the GPS lat and lon data. You might want to have a look at the DC path_follow.py template gps.py part. It parses either the GP or GN NMEA RMC message from the GPS output. Communication with the GPS is at a baud rate of 115,200 and I have my GPS/RTK GPSs setup to send only the NMEA GNRMC message over the serial link to reduce message parsing time and allow for the higher baud rate.

Additionally, you might want to consider replacing the IBT-2 motor drivers with a RC signal input motor controller that can take and convert steering and throttle RC PWM input into differential steering commands. I know that it is much more expensive than the IBT-2s, but it offloads a fair amount of processing from the RPi. At Donkey Car we have developed a prototype RC HAT that can decode and encode RC steering and throttle PWM signals and communicate with the RPi over a Serial UART link with this DC part: robohat.py. This will mean that you will have to use a GPS with a USB interface since the RC HAT uses the only RPi hardware Serial UART.

Attached is a photo of the prototype RC HAT which uses a KB2040 to encode/decode RC PWM signals and communicate with the RPi. RC HAT_KB2024 001

Regards, TCIII

acredsfan commented 1 month ago

@TCIII,

You've definitely got far more experience with these systems than I do, so I really appreciate your insights. As you can probably tell already, I was first working on getting all of the components to work individually, which for the most part I had. I was then trying to integrate them all into a cohesive system and then refine from there. A lot of the things I have, such as using gpsd to acquire lat and lon were because those were methods that had a lot of information/examples that I could use to get it working. That usually means there wasn't much in the way of alternatives considered and refinement.

As far as the suggestions you've made, I really like the RTK GPS upgrade and the fact that we can drop in the Donkey Car gps.py to support either GPS option (RTK or not). I will remove the multiplexer from the system, and work on figuring out the best module to use for the dual ToF sensors unless you have a suggestion ready to go. I'm also going to replace the MPU9250 with the BNO055 so that will require new code. I also really like taking compute resources off the RPi with the motor controller you've described, but to clarify, are you saying the motor controller and RoboHAT MM1 are what are required, or some other configuration? The RoboHAT appears to have functionality that is redundant with the current components in the IMU and voltage sensor. I may leave this upgrade for later in order to focus on getting the robot running then make that upgrade.

I have no pride in ownership of the code, so feel free to fix or improve anything you see fit. I ultimately wanted this to be a project that makes building a raspberry pi powered robot possible for as many people as possible while allowing me to learn more about robotics. I hoped this could become a collaborative effort, so please keep the observations coming. I'd like to learn as much as possible.

Thanks, acredsfan

TCIII commented 1 month ago

@acredsfan,

I think that I may know why you had trouble with the L298N motor controllers. For each motor IN1(3) and IN2(4) are used for directional control and take ON/OFF logic control. ENA and ENB control the speed of the motor using PWM (not RC PWM). This tutorial explains how to use IN1(3), IN2(4), and ENA(B) for each motor.

Regards, TCIII

TCIII commented 1 month ago

@acredsfan,

The RC input motor controller will work with the DC RC HAT shown in the photo in my post above and it will cost less than $20.

Regards, TCIII

acredsfan commented 1 month ago

I'll take a look at how I had configured the L298s it's entirely possible I had it wrong. As far as the motor controller upgrade, $20 would be a worthy investment. Can you link me to where I can purchase the DC RC HAT so I have the right item?

TCIII commented 1 month ago

@acredsfan, The DC Maintainer who I am working with on the new RC HAT keeps changing the PWB layout, but I think that he has finally stabilized the PWB layout. The new RC HAT will have three RC PWM inputs and two RC PWM outputs (throttle and steering) plus an I2C connection, pads for an I2C OLED, and 5vdc power for a fan when using a RPi 4B. We should have proof of design PWBs by late next week and if all goes well the new RC HAT should be available for sale by the end of May or early June. I will let you know when they are available. You should be able to send steering and throttle commands to the RC HAT which will convert them to steering and throttle RC PWM signals.

Regards, TCIII

acredsfan commented 1 month ago

Awesome, I look forward to the availability of this.

TCIII commented 1 month ago

@acredsfan, I don't mean to sidetrack you with my suggestions. If you are comfortable with you original parts list then go for it if you have a working functional prototype. Then you can work at upgrading the components and improving the functionality of your autonomous lawnmower.

The ArduRover version of my autonomous robotic lawnmower control module's performance will probably far outclass your present prototype. However it comes in at around $1,500 due to the use of the Pixhawk 6x mini controller, the Sparkfun NEO-F9P RTK GPS module, the survey grade L1/L2 GPS antenna, the Holybro M10N GPS module, the Holybro RM3100 Professional Grade Compass, the lawnmower chassis itself, and not even counting the cost of the Base Stations.

The other control module is much cheaper and uses a RPi 4B 4GB, a Robo HAT MM1 (to be replaced by the DC RC HAT), a Sparkfun NEO-F9R RTK GPS, and a survey grade L1/L2 GPS antenna. However, I am using the DC path_follow template which uses a primitive, compared to yours, webui to indicate the cutting path being recorded and played back. Your webui and cutting path planning is what attracted me to your project and it would be nice to come up with a hybrid of your lawnmower operating system and the path_follow template.

By the way, I live in Central Florida and have a lawn consisting mainly of St. Augustine grass which is very coarse and has long runners. That is why I developed the lawnmower chassis seen in my DIY Robo Cars blog post. Your lawnmower chassis would just kind of float on top of the St. Augustine grass which would probably break the 3D printed cutting head.

Regards, TCIII

acredsfan commented 1 month ago

You're perfectly fine with your suggestions. I'm just trying to weigh cost/benefit outcomes with each. I think the upgrades to use RTK, a better motor controller option (I'd be interested in the interoperability for the 12v motors I have driving the wheels), and the upgraded IMU are worth the added cost, and outside the possibility of adding a base station, are pretty cost effective. I live in Southern Ohio, so definitely quite different as far as grass types. I'm still concerned about the durability of mine, but since I started based on another project and it took a few weeks to print the entire thing, I decided to reuse it.

I'm really excited about merging the webui with your path following method as I was really prepared for having to use a lot of software computing to overcome the lack of precision with the GPS.

Your robot in the blog is definitely beefier that mine, that's part of the reason I like the heavier worm gear motors for the wheels so hopefully it can maintain traction in my lawn which has some slope to it. Ultimately, I think it would be nice to have some modularity to the project so the user can decide whether to go budget or more premium and still have a similar UI experience, but that's maybe more wishful/future thinking.

Thanks, acredsfan

TCIII commented 1 month ago

@acredsfan, Sounds good to me.

I am sure that together we can put together a parts list from budget to premium by using modularity with most of the cost increase coming from moving from GPS to RTK GPS as most of the other hardware is not that expensive.

Regards, TCIII

TCIII commented 1 month ago

@acredsfan,

If you would like to explore using the upcoming new DC RC HAT, as an alternative to using the RPi to generate and decode RC PWM signals, you might want to take a look at the DC robohat.py part, that allows the RPi to communicate with the RC HAT over the hardware serial UART, and how it can be integrated into your motor control code.

Since the RC HAT is using the hardware Serial UART, I would recommend switching the GPS to a USB input and bumping the baud rate to 115,200.

Observation: It has been found that the pigpio and RPi.GPIO libraries will not work on the RPi 4B version 1.5 and not at all on the RPi 5 running the Bookworm OS.

Recommendations: 1) It might be wise to run your code in a Python virtual environment by using the following code snippet to create a virtual env:

python3 -m venv env --system-site-packages
echo "source ~/env/bin/activate" >> ~/.bashrc
source ~/.bashrc

2) It might be a good idea to provide a link to how to obtain a Google Maps api key.

Here is a photo of the new RC HAT pwb: RC_HAT

The IC U1 footprint is for a Waveshare RP2040-Zero. Unfortunately I disagreed with the PWB designer who decided to power the RP2040-Zero, and the RC Receiver with the Battery Eliminator Circuit (BEC) in the vehicle Electronic Speed Control (ESC), so I will provide 5vdc from the RPi GPIO Bus to the RP2040-Zero and the RC Receiver and cut the BEC V+ power trace from the Throttle Servo output connector from the rest of the pwb 5vdc traces. The reason I disagreed is that Traxxas and some other RC manufacturers' ESC BECs supply 6vdc, not 5vdc, and the maximum working voltage of the RP2040-Zero is 5.5vdc as there is no onboard voltage regulator.

Regards, TCIII

acredsfan commented 1 month ago

@TCIII,

Thank you for these observations! I'm digging into the code you've shared for the RC HAT, I have no issue with switching the GPS from serial UART to USB. I'd love to get an updated schematic of my current setup to you to get your input on what can be improved and what needs to be updated for the RC HAT. I'll work on updating when I get a chance.

Thanks, acredsfan

TCIII commented 1 month ago

@acredsfan,

Sounds great. A reworked RC HAT pwb will be available in about 10 days for me to tryout. The designer of the RC HAT pwb decided to power the Waveshare RP2040-Zero module from the RPi GPIO Bus 5vdc in this latest pwb iteration, however the RC Receiver is still being powered by the ESC BEC unfortunately.

I plan to use a CM4/CM4 IO Board for you project because it has a built-in 12vdc to 5vdc regulator, a battery backed RTC, and the CM4 module has a connection for a rubber duckie antenna besides the pwb antenna which is covered by the CM4 cooling fan.

Attached is a photo of the CM4/CM4 IO Board: CM4_CM4 IO Board 001

Regards, TCIII

TCIII commented 1 month ago

@acredsfan,

You might want to consider using the PNI RM3100 Professional Grade Compass in place of the compass in the MPU9250. Here is a link to an RM3100 Python driver. Additional information concerning the RM3100 Python driver.

My recommended replacement for the MPU9250 is the BNO085. Here is an Adafruit tutorial on using the BNO085 with Python. The BNO085 does have a magnetometer, but I think that the standalone RM3100 is far superior.

I will be glad to support you in these component upgrade endeavors as I already have a BNO085 IMU available and I plan on ordering a RM3100 from PNI.

Regards, TCIII

TCIII commented 1 month ago

@acredsfan,

To reiterate some gotchas: 1) RPI.GPIO will not run on the RPi 5 running the Bookworm OS. 2) There are issues running RPI.GPIO with Bookworm on the RPi 4B.

Regards, TCIII

tlj1899 commented 1 month ago

I wanted to let you both know that I'm in the process of printing out the parts for the mower from Cults3D and I want to collaborate on this project. I have experience with electronics, robotics and programming and I want to first help with finalizing a baseline list of electronic parts for the mower.

acredsfan commented 1 month ago

Hi @tlj1899,

Thank you for your interest in the project, I welcome anyone who would like to collaborate on this project! Let us know any questions, insights, observations, or suggestions you have.

Thanks, acredsfan

TCIII commented 1 month ago

@tlj1899,

Since I live in Central Florida I have a front yard composed of St. Augustine grass which is a creeper style of grass composed of very thick creepers and thick blades. This is why my autonomous lawnmower has a 12 vdc electric scooter cutting head drive motor and a three bladed cutting head. That cutting head can also be purchased with metal blades. You can view the construction of my autonomous robotic lawnmower here.

If your lawn consists of fine blade grass, @acredsfan's present component list for the cutting head drive motor and cutting head will probably be sufficient.

Additionally, all of the successful articles I have read on building an autonomous robotic lawnmower do not use either the NEO-M9N or the NEO-M8N due to their poor horizontal accuracy of 2.0 - 2.5 meters. On a good day a Rover RTK GPS module can get down to a horizontal accuracy of under two inches. I have been using this Beitian BT-160 L1/L2 antenna, which unfortunately is not currently available now, with my RTK GPS Rover modules. Last Christmas I paid $58 USD for my first BT-160, but after Christmas the price went up to $78 USD which is still a very good price. A decent alternative L1/L2 GPS antenna is this Sparkfun antenna. I think that you are going to find that you get what you pay for in the way of horizontal accuracy.

As far as the PX112R-EVB goes, the down side is the FedEx shipping cost from Taiwan which cost me $55 USD as I live in Florida. It might be a little less or more depending on where you live. I have both the Evaluation Board, which I am using in a Base Station and the NS-HP-GN2 : PX1122R L1/L2 RTK BREAKOUT BOARD, which requires a UART to USB adapter, which I am using as a RTK GPS Rover with an RPi 4B 4GB.

Regards, TCIII