ROS on GoPiGo3: Adventures in using other people's code

My conversion of the ROS(1) gopigo3_node to ROS2 had been progressing well until I got to the servo position topic.

ros2 topic pub /servo/position1 std_msgs/msg/Float64 ‘{data: 0.785}’ ← NOTE it wants radians

Ugh - who thinks in radians?

  File "/home/pi/rosbot-on-gopigo3/handsonros2/install/ros2_gopigo3_node/lib/python3.8/site-packages/ros2_gopigo3_node/", line 132, in <lambda>
    self.subscription = self.create_subscription(Float64,  "servo/position1",      lambda msg: self.set_servo_angle(self.S1,, 10)
  File "/home/pi/rosbot-on-gopigo3/handsonros2/install/ros2_gopigo3_node/lib/python3.8/site-packages/ros2_gopigo3_node/", line 217, in set_servo_angle
    self.g.set_servo(servo, pulse)
  File "/usr/local/lib/python3.8/dist-packages/gopigo3-1.3.0-py3.8.egg/", line 628, in set_servo
  File "/usr/local/lib/python3.8/dist-packages/gopigo3-1.3.0-py3.8.egg/", line 267, in spi_transfer_array
TypeError: Non-Int/Long value in arguments: 871aad10.

The call to the gopigo3.set_servo(servo,pulse) complained that the pulse parameter was not an integer. Turns out it was a numpy integer, but not a pure Python integer. The easy fix: pass int(pulse).

But was it working in the original code? My thoughts turned to @KeithW and his Finmark robot,

but I see Finmark does not have a servo. Perhaps the original author did not have a servo on his bot as well.

1 Like

Looking at the book, it seems that @brjapon did. Here’s a snippet of the color version (from the pdf companion) of the picture on p 302 of the book:

In earlier pictures the distance sensor was on the servo, and it seems to be in the same location on the robot. That said, in the URDF the distance sensor has a fixed joint to the base_link. So there is no provision for the distance sensor to pivot w/o pivoting the robot.

For my own robot I didn’t add a servo for simplicity’s sake, since it wasn’t part of the URDF.


Lots of people, especially if you want to do any kind of math that’s more complicated than counting your fingers and toes.

If I remember rightly, the easygopigo and gopigo libraries default to radians and “degrees” are a special case with a conversion method. Even the original Remote Camera Robot code did all the math in radians.

Vector algebra in degrees is a devil-spawned nightmare. The exact same thing in radians is trivial. If you don’t believe me, try calculating the total impedance of an inductor and capacitor either in parallel or series.

In degrees? You gotta bottle of Johnny Walker? You’re going to need it!

It’s a lot like the metric system. Once you get your head around it, it really begins to make sense.


You mean there are people that want to do math? The only keys that wore out on my HP-45 calculator were +,-,*,and div. I was a mechanical engineering student so I didn’t have to understand math, I had a mechanical slide-rule that turned math problems into mechanical manipulation. Who really understood why I needed to know how Pi is derived, or those awful infinite series things?

Really, there are people that want to do math?


I nearly ran out of class the first week of solar engineering when they put up the math fur plumbing the roof-top collectors.

I managed to do the math during college only because I had to. As soon as I learned there as no math in writing software, I switched careers.


Take one case in particular:

My robot is moving in a straight line forward at “X” velocity. I move the joystick slightly to the left. The left wheel needs to slow down and the right wheel needs to speed up.

What is the new ratio of the wheel velocities?

The correct answer involves differential calculus. A “close enough” answer involves the ratio of the sine and cosine of the angle desired.

Next question? :wink:

1 Like

You see, there you go computing from first principles. These days everything is about knowing which library hides the math.


Say WHAT?!!

What software did you ever write?

I can’t remember any software I wrote of any complexity that didn’t involve some math aside from arithmetic.

In some cases the math can be done once and stored as a constant, (or table if you have the memory.) sometimes at compile time, more frequently at run time and hopefully you can do it early enough so that the time to do the calculations is swamped by the startup time.

Math is inevitable. The best you can hope for is to be able to simplify the calculations into simpler and faster forms.

1 Like

Memory and time are not inexhaustible resources, especially on a Pi.

If I can simplify a calculation and avoid loading an additional library or two, I save time, debugging angst, and the stress of some bonzoid library function being “depreciated” (or the syntax radically changed) and breaking things in subtle ways.

Maybe I’m an “odd duck” but I try to avoid external dependencies if I reasonably can.

It’s probably my 8-bit and embedded controller past haunting me.


Death is inevitable, everything else is negotiable.


That was where the professor lost me every time. I am known for making things more complicated than needed (because I never understood the why beneath the simplification examples used to teach.) Simplification just never made it into my toolbox.


I strongly suspect that I’m “on the spectrum” somewhere, but complexity totally frustrates me.

(Look at the nipple.js code in the remote camera robot project. It’s a rat’s nest IMHO with eff-all to guide you.)

Once I get to more than a few dozen lines of code, (exclusive of comments, they’re easily the largest part of my programs), I begin looking for ways to either simplify or “divide and conquer”.

(If the number of comments becomes unwieldy, I consider removing some of them and then create a “how it works and why I did it that way” document referencing the code file.)

Later on I read a physiology article on programming efficiency and there was a study done on the ideal “chunk size” that a program could be to be understandable and maintainable.

Their findings? About 80 lines of actual code, plus or minus. Beyond that and people became scatter-brained and tended to write crap code.

I vaguely remember mention of a dev group somewhere that had a line-count limit as a part of their coding style and practice rules. If a section of code was too long it was rejected to be either revised or broken up into more manageable modules.


If you don’t know the “first principles” you cannot determine what is essential for a particular task and what can be safely ignored.

I remember reading about an interesting mathematical theorem that allows simplification of certain bizarre and difficult equations by saying that all factors in the equation less than [something I don’t remember] can be ignored because they won’t affect the outcome.

The theoretically necessary bandwidth for clear and reliable FM reception is represented by an infinite series of sideband nodes described by Bessel functions. However, once the amplitude of a particular node, and all those above it, are below some small value, you can safely ignore them without affecting perceptible signal quality.

Likewise, because the angular accuracy of a joystick is relatively bad, I don’t need insane precision, therefore I know that the ratio between the sine and cosine will be sufficiently accurate for my needs.

First principles have their uses. :wink: