mi4g6u
Posts: 5
Joined: Tue Oct 24, 2017 5:21 pm

Ultrasonic Sensor Readings in Different Thread

Wed Oct 25, 2017 11:05 pm

Hello Everyone,

I am creating a project that involves autonomous navigation through the use of ultrasonic sensors and motor encoders. I am doing the project in python. I have created a function that controls the speed of dc motors using the motor encoders that works well. I would like have this function running constantly on its own thread so i can do the navigation on a different thread and just change the speed of the motors as needed.

The problem i have is when the motor speed thread is running it screws up readings from the ultrasonic sensors. I believe this is because this is because the motor speed thread interrupts the ultrasonic senors while they are waiting for an echo.

Does anyone have any advice? Maybe there is a way to block all other threads while the ultrasonic sensors are reading?

Thank You!

User avatar
OutoftheBOTS
Posts: 711
Joined: Tue Aug 01, 2017 10:06 am

Re: Ultrasonic Sensor Readings in Different Thread

Thu Oct 26, 2017 9:52 am

yes this will be a problem for sure. For what your doing timing is important for both the encoder readings and motor speed adjustment and ultra sonic readings. I would run eveything in 1 thread and not use multi threads as it is going to screw with your calculations

First your going to have to work out what freq is best for your robot to run on, this is usually governed by the resolution of your encoders and the speed that your robot is going. There is no point in doing calculations to adjust motors if there hasn't been enough data come in from encoders. If you r using reasonably high resolution encoders then 20hz will be fine if not maybe need a lower update freq.

Here is some code that I just tapped out to give you an idea. You can see it is constantly testing for encoder ticks but only runs the rest of the code once every 1/20 of a sec.

Code: Select all

import time

start_time = time.time()
freq = 20
time_gap = 1/freq

def read_ultrasonic ():
  #insert code to read ultrasonic sensor and return distance

while True:
    #insert code to check for encoder tick and if there has been a tick then encoder_ticks += 1
    if time.time() - start_time > time_gap :
         distance = read_ultrasonic ()
	 #insert code to calucate RPM based upon encoder_ticks counted in time_gap
	 encoder_ticks = 0
	 #insert motor PID control code to adjust motor power based upon the desired speed against the real speed
	 #insert any other code needed to run the robot, realise it will only run at freq of robot 20hz

mi4g6u
Posts: 5
Joined: Tue Oct 24, 2017 5:21 pm

Re: Ultrasonic Sensor Readings in Different Thread

Sun Oct 29, 2017 7:48 pm

Thank you for the response! I will try to do it like this.

stijn.ghesquiere
Posts: 26
Joined: Sat May 19, 2012 9:44 pm

Re: Ultrasonic Sensor Readings in Different Thread

Wed Nov 01, 2017 9:24 am

Are you using the threading module or the multiprocessing module?
It can make a big difference depending on your python code. It is to say: if your code is pure python, the GIL is not released (https://wiki.python.org/moin/GlobalInterpreterLock). In practice, this means that python shares cpu time between processes if they do not release the GIL.
If you have a raspberry pi 2 or 3, and you use the multiprocessing modules, you will get independent processes that will not disturb each others timings.

User avatar
OutoftheBOTS
Posts: 711
Joined: Tue Aug 01, 2017 10:06 am

Re: Ultrasonic Sensor Readings in Different Thread

Wed Nov 01, 2017 8:48 pm

Are you using the threading module or the multiprocessing module?
In the original post he was using threading so it is computing in serial. Yes you can get around the problem by using mutli processing as it will compute in parallel but this opens up many new problems like if you put your encoder counter on a separate process going around the GIL then it is possible for the encoder counter to be writing to counter variable at the same time the PID motor counter is reading the variable causing corruption of data.

The solution that I gave is what I learned from a very successful robot designer that has been winning autonomous robot comps since the 80s. With autonomous robots timing and level of priority of behaviors is super important. As you keep adding sensors and behaviors and you use multi processing you will end up with lots of things conflicting with each other. The solution that I set out u can keep adding more sensors to read and the behavior response to that result of the data from that sensor and add them in the order of importance that you want to test in.

Timing is also critical, as we move from cyber space into the real world with a robot we hit real world limitations like the motors will only be so responsive to speed changes at. So if you read a sensor like the motor encoders and realize that the robot is under speed so the PID adds more power there is not point reading the encoders a pico second later as even though the PID has increased power it will take a little time for the motors to pick up speed from the increased power. So the solution that I have given allows you to control the freq of the robot processing

stijn.ghesquiere
Posts: 26
Joined: Sat May 19, 2012 9:44 pm

Re: Ultrasonic Sensor Readings in Different Thread

Wed Nov 01, 2017 9:20 pm

@OutoftheBOTS: Don't worry, I'm not arguing that your solution isn't good. It's elegant.
I just wanted to point out that if threads interfere in each others timings, multiprocessing is an alternative. And if you use a shared value in python multiprocessing the correct way, operations on that value are atomic and locked. So you won't have data corruption.
More info about atomic locks: https://eli.thegreenplace.net/2012/01/0 ... processing.

I'm not saying that multiprocessing is the best approach in this case. But I do believe that it's a good way to learn multiprocessing. And why not try out different approaches? It can be quite surprising at times what works best. I would try both approaches.

Return to “Python”