ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question

PID: Infinite loop in a ROS listener node?

asked 2017-03-15 05:47:55 -0500

Oddity gravatar image


My team and I are participating in the 2017 Eurobot competition, and we are trying to use ROS on our robot. One problem we are facing, is how to write a PID node in ROS. I know there is an available PID node, but with the particular electronics of our robot, it does not seem to be usable in our project.

To be brief, we use a Raspberry pi 3 as Central Unit, which is connected to an FPGA via SPI. The encoders from our motors are connected to the IOs of this FPGA. So the principle of the PID that we use right now is the following: We have an infinite loop which reads (via the SPI) two counters on the FPGA: one for the encoder motor, and one for the elapsed time. Then, with these counters, we compute (on the rpi) the speeds of each motor, and we use the PID to compute the needed command to send to the motors.

So right now, I have written a ROS node which publishes a topic with the desired speed, but I'm struggling to write the PID in a subscriber node. My problem is that in a subscriber node, every time the node reads a command from the topic, it starts a function, but I can't simply copy my current infinite loop in this function, otherwise it will run forever. And if only copy-paste the content of my loop in the function called by the subsciber, the function will only be called once if the publisher node doesn't publish a new desired speed.

So I was wondering if one of you has already faced this problem, and if he/she could help me on this?

Thanks a lot ! =)

edit retag flag offensive close merge delete

2 Answers

Sort by ยป oldest newest most voted

answered 2017-03-15 11:04:55 -0500

Airuno2L gravatar image

If I understand you're problem right, the answer is to use a class. The PID infinite loop is a member function of the class and the subscriber callback function is also a member function of the class. Then the desired speed is a member variable of the class which is set inside of the subscriber callback function every time your publisher sends out a desired speed.

edit flag offensive delete link more

answered 2017-03-15 11:35:45 -0500

AndyZe gravatar image

updated 2017-03-15 11:40:52 -0500

Alternatively, you could place the loop on the Publisher side. It would publish at a constant rate even if the value isn't changing. The ROS Publisher/Subscriber tutorial has an example of publishing at a fixed rate.

For the subscriber callback, you would run one PID iteration with every new message. You would need some memory on the Subscriber side to store the integral and the previous error, which you could do with a class (like Airuno said) or with global variables. If you use global variables, it's good practice to put them in a namespace.

edit flag offensive delete link more


But the PID iterations need to be constantly running to maintain a desired speed, not just when a new speed is commanded.

Airuno2L gravatar image Airuno2L  ( 2017-03-15 12:22:58 -0500 )edit

Yeah, he'll have to re-publish even if the speed command doesn't change.

AndyZe gravatar image AndyZe  ( 2017-03-15 12:50:23 -0500 )edit

Question Tools



Asked: 2017-03-15 05:47:55 -0500

Seen: 903 times

Last updated: Mar 15 '17