UGV Rover - with & without ROS2

Because I so love repeating myself - I really don't, trust me, but I tend to end up doing that - a lot!

I've decided to "start again" with the Waveshare UGV Rover.

"why?" because, that's why.  well, I've been around the houses with this thing so many times that I've lost track of how to reproduce the state of where I'm at & how to recreate.  Also, for some odd reason I managed to break the installation that I had in place and I couldn't get any imagery from the camera. hmmm... not sure what I broke, or if indeed it was actually me & not an update?


Anyway, so here I am again, going back through a "start from scratch" install & setup.  This time I thought, "y'know, I'm gonna f**k this up a few times, I best document the steps so I can run through it faster the next 5 times I do this" :-)

First step.  Get the waveshare .img file - that saves LOADS of time, basically it is Raspberry Pi 5 OS (Bookworm) with the waveshare github repo in place and executed.  Put simply, there is a directory named, "ugv_rpi" that has a Python virtual environment created that has all the required libraries etc.. installed and ready to go.

Get the .img from HERE: 

https://files.waveshare.com/wiki/UGV-Rover/UGV_S20_240423.zip

Then do the usual and burn the .img onto a 32GB SDCard:


Also, it is compulsory to listen to an online music streaming service, like spotify and listen to something like this compilation:


https://open.spotify.com/playlist/37i9dQZF1DX9wC1KY45plY?uid=34643266313330363731646566313465&uri=spotify:track:3fH4KjXFYMmljxrcGrbPj9

It's not compulsory, but it is. So, do it. Do it now, whilst you wait for the [verify] to do it's thing.


Right, now get that SDCard out and get a pair of pliers.  Yes, they ARE needed, you need to do some surgical rear end fiddling to get the existing SDCard OUT and the new one IN.  You'll know what I mean if you have one of these UGV Rovers infront of you.  Also, you might need a torch, maybe a head torch would have been easier than trying to hold the torch in my mouth :-D

Right, make sure that it's firmly inserted in properly, it can go in sqwiffy, so make sure it is properly in, but don't push to hard, you might break something - "ooerr matron!"

in fact you have time to watch the whole YT snippet:


Good god, I get distracted far too easily.

I chose to do some editing for the imager setting, so I have a default user of ws/ws, I have the WiFi pre-configured & I have the locale setup, just so I don't have to do it after I boot up.

Now, after booting up, there should be a few restarts, might even have to just turn off the UGV Rover and start it up again, it should flash the lights, possibly even talk to you, you then login [ws/ws].

Now, the App.py thing will be running, we need to turn that off as it'll cause us grief when trying to do our manual work.  We'll leave the jupyter notebook instance running though.

$ crontab -e

just comment out the first line.  Save & we'll reboot later.

Now it's time to install the Docker Engine for ROS2 that we'll use later on.  Let's do this properly shall we, none of that docker.io b*ll*x, let's do it properly, as per the install guide.

Why do I have such b33f with docker.io? Well, finally the official page has added it to the "uninstall that sh!t" list - yes, it caused me to lose a lot of time in the past, hence pointing it out:


https://docs.docker.com/engine/install/debian/

Then basically run through the instruction steps, I'll replicate here, so I can copy & paste from the Raspberry Pi5:

# Add Docker's official GPG key:

sudo apt-get update

sudo apt-get install ca-certificates curl

sudo install -m 0755 -d /etc/apt/keyrings

sudo curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc

sudo chmod a+r /etc/apt/keyrings/docker.asc


# Add the repository to Apt sources:

echo \

  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian \

  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \

  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo apt-get update


sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin


sudo groupadd docker

sudo usermod -aG docker $USER


Now, you can LOGOUT here or just REBOOT - reboot is easier as the crontab change will kick-in.

I have noticed that the screen hangs on "plymouth-reboot.service" with a Raspberry Pi logo on the screen - I "believe" what it's trying to do is execute the restart, but something is locking the machine, so just power it off manually & power it back on again. Oh! I left it for about 3 minutes & it DID reboot! oops, maybe I was impatient before!

After the reboot, open a web-browser and bookmark:

http://localhost:8888

and set it to always bring up this page - this way you will have access to the Jupyter Notebook that is running at all times, it's handy for reference if nothing else.

You have an option here.  You could go & pull out the SDCard & make a backup of it.  Hmmm.... or just remember to redo the steps above, whatever you think is going to be quicker / easier.


What I have figured out is that if you try to access the camera and you get errors from the Jupyter notebook code, then the app.py or something else is locking the USB - so you'll get an error about not being able to access the camera.

Test by opening up the [16. Controlling Photo Capture with Buttons.ipnb] and running the code in the cell.  Press the [Photo] button and you should see something. Oh look, I see "2" of me, that's what I'm saying there, honest ;-)


"Just What I Needed" - The Cars : perfect timing to now be playing :-D

Now, let's do a little bit of cheating shall we?!


As mentioned earlier, the UGV .img has a pre-installed setup of their Python virtual environment.  Let's take a copy of that, we don't have to of course, but y'know, I'm bound to "break it", so having a copy is an easy option, it's only 1GB of space.

So, copy this Directory from here & copy to a new directory that you've pre-created:




oh, see that ugv_control directory - yeah, drag that inside that directory you just copied over.

Now, open up a Terminal & source the virtual python environment:

$ source /home/ws/dev/ugv-env/bin/activate

(ugv-env) ws@raspberrypi: cd /home/ws/dev/ugv-env/ugv-control/

(ugv-env) ws@raspberrypi: python3 test_move_01.py

As you can see the code for this is on the left-hand side.  It's very simple.
You need to have the base_ctrl.py and the config.yaml code copied over from the original source as this is imported in order to communicate with the UGV rover.


Running the code should now do this:  ( "Solsbury Hill" - Peter Gabriel : nicely timed)


amazing.  not really. But, it does show that from native Python code we can communicate with the UGV Rover from the "lower" board to the "higher" board. ie. from the ESP32 board to the Raspberry Pi 5 device via the Serial comms.

Oh you didn't know about that?  

Yeah.  There's that.  The "brains" of the UGV Rover is inside the ESP32 board, which free's up the Raspberry Pi 5 to do "other stuff" - which is how I had YoLo v8 running on it previously to do advanced Image analysis stuff.  anyway.

What now?

Ah yes, back to Docker Engine!

Before we do that, let's clean-up properly.  From that CLI, type: deactivate

There we go, exited the virtual python environment nicely.  You'll note the (ugv-env) has gone away.

.

Yes, this does irk me a lot.  I am actually "using" Python, begrudgingly, but it does amuse me that as it is soooo Visual Basic 6 .dll hell still, the only way to solve the Python sh!t c*ck up is to make an isolated installation version for everything you do so you can get the f*king code to work due to library version conflicts.  what a f*king shambles.  anyway, I still stand by my assessment, Python is a cardboard tool.  You don't use it for real, it for "testing" / "PoC", before you do it again with something real.


I am actually wearing "van slippers" too - hahahahahhahahahahahahaaa! what? it's 6'C, it's cold! and I've just made a hot chocolate!!! hahahahhahaaaa

Now, onto the something "real".  

.  "Drive" - The Cars : now, that takes me back to xmas as a teenager in the late 80's. sigh.

$ docker image pull ros:humble-ros-base


Oh, nearly forgot, we sometimes like a UI for things, so let's install Portainer:

$ docker volume create portainer_data

$ docker run -d -p 8000:8000 -p 9443:9443 --name portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce:2.21.5

Then we can open a web-browser at https://localhost:9443/

admin/adminadminadminadmin

"Rocket Man (I think It's Going To Be a Long, Lo.." - Elton John : again, perfect timing.

"I'm not the man they think I am at home". never a truer word said.


Now, let's create a container from the image we just downloaded:

$ docker run -t --privileged ros:humble-ros-base

This will just run the instance up, let's exit straight away.  You'll notice in Portainer that it is now a [stopped] container.  Let's just start it again from the UI.

"Don't Stop" - Fleetwood Mac : oh yes!........."don't stop"...."it'll soon be here"...."yesterdays gone"

Now we can just connect to it and install the extra ROS2 libraries for the demos.

In Portainer, I see that the container got a random name of "hungry-wozniak" (lol hungry apple!), it's still running, so now I can do the exec connection command:

$ docker exec -it hungry-wozniak /bin/bash

root@848a093c00c:/#

root@848a093c00c:/# apt-get update

THIS IS NEEDED to make sure we can get the ROS demo node code. do it.

root@848a093c00c:/# apt-get install ros-humble-demo-nodes-py

root@848a093c00c:/# apt-get install ros-humble-demo-nodes-cpp


SWEET! We're now in a good place to TEST this setup.

First first, we need to add this entry to the .bashrc file, just so we don't have to type it every time:

$ apt-get install nano

$ nano ~/.bashrc

scroll to the end and add:

source /opt/ros/humble/setup.bash

[ctrl+x, y, enter]
We can exit this connection now, so the next time we login we will execute that new change.

"The Logical Song" - Supertramp. lol.

Now we need to make 2 connections to the running container.  Two terminal windows please:

[Terminal 1]

$ ros2 run demo_nodes_cpp talker

[Terminal 2]

$ ros2 run demo_nodes_py listener

This will make sure that we can test both the C++ and Python nodes are working.

We should now see the following:


"One Way Or Another" - Blondie : "I'm gonna get you, one way or another" hahaha, yes. finally.

.

Right, that's all the BASIC setup in place.  I need to now figure out how to get the "ugv_ws" directory inside the container (should be simple enough as it has internet connection) and then do an "installation" so that all the ROS workspace code is then available & the same Python code can now be run, but this time as ROS pub/subs!

How did that take over 2 hours?!?!  This is why I needed to write this down.  This is great being in my head for a few days, but give it a week or two & I'll have forgotten half of these steps.


We'll finish on - "Under Pressure" - Queen, David Bowie = perfect timing



Comments