Shop OBEX P1 Docs P2 Docs Learn Events
Bot rpm measured great on propmod, now I need to improve it — Parallax Forums

Bot rpm measured great on propmod, now I need to improve it

P!-RoP!-Ro Posts: 1,189
edited 2009-08-24 03:07 in Propeller 1
A while back when I was more of a beginner I created code to detect rpm on my robot's engine. It is very inefficient though, taking up two cogs. One for counting, one for reading information and posting results. This also made it inaccurate, with results of +-60rpm every 1 second. I would like to improve it, but I'm trying to think of how I can do it with maximum efficiency, something very important considering how many other tasks I intend to do with the prop. Any suggestions? I'm hoping to possibly predict the time in between pulses and to do tasks in there--that might be asking a bit much though.
I have posted the old code, but sometime later I plan to upload a 1 cog version once I have time to work on it. Also posted are some pics of it working, running off of batteries from an old robot.

Just suggestions for now, I'm looking for ideas on how I should attempt this. Thanks.

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
PG
1600 x 1200 - 441K
1600 x 1200 - 339K

Comments

  • W9GFOW9GFO Posts: 4,010
    edited 2009-08-23 02:34
    I would look into using a counter module.

    Rich H
  • TimmooreTimmoore Posts: 1,031
    edited 2009-08-23 04:57
    Heres an example of using a counter to time pulses, if you look in the attached file in routine Poll for the code
        invalue := ina[noparse][[/noparse]VexPin]                              ' get current receiver output
    ...
          WAITCHANNELHIGH:
            if invalue                                      ' start of the channel values
              statetime := cnt                              ' using cnt is inaccurate - it depends on polling timing
              frqa := 1                                     ' so use counter to measure low time
              phsa := 0
              ctra := ctrmode                               ' set counter to count clkfreq when pin low
              state++                                       ' state := GETTINGCHANNELHIGH
          GETTINGCHANNELHIGH:
            if phsa > 0 AND invalue                         ' wait for start of actual channel value and end of channel value
              ctra := 0                                     ' stop counter
              channel[noparse][[/noparse]channelindex] := (phsa + 40000) / uS_tix ' update channel time with uS time
    
    


    you see it using a counter to time a pulse, the routine needs to be polled but a much low timing interval than it measures the pulse width, it just needs to be called atleast once during the pulses so I can poll for the pulse length rather than requiring a cog to measure it
  • P!-RoP!-Ro Posts: 1,189
    edited 2009-08-23 05:51
    I've never used a counter before, but if it can save me some time it sounds very beneficial. There is one thing I wonder about, however. One of the adds I had to make in my above code to make it work was a pause 10ms command in between reading the pulses. Although I do not have any tools to check it, it seems the output fluctuates to some extent as the spark plug fires. Could errors of this nature be ruled out by either hardware or in the way I run the counter?

    And thanks for the advice and code, it is very helpful.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    PG
  • TimmooreTimmoore Posts: 1,031
    edited 2009-08-23 06:28
    Sounds like the spark park is generating noise which is picked up by the rpm sensor. This generates extra edges in the signal, no the counter will not ignore this without help. There is a couple of things you can do - and probably both - if the 10ms between rpm readings works - do this between readings using the counter. The other thing is to filter the sensor readings - I would do a couple of things - very short readings should't happen - so ignore readings that are else than some value - its dependent on your system so what is the min pulse width that makes sense and ignore shorter ones, then do this

    reading := (oldreading *7 + newreading)/8

    It filters noise by not letting the reading change too quickly
  • P!-RoP!-Ro Posts: 1,189
    edited 2009-08-23 18:21
    It's possible, but if I am slowing it's changing will it affect timing? I was hoping to find rpm by using time between pulses to get more accuracy. Also, what are the prices I'll be looking at for this chip? From looking on Digikey it seems many can be quite pricey, almost seeming like I should just get a second prop once I have the space filled up, but even that could be used up should I start using image processing (I'm not sure yet, I haven't tried much with the code to control anything).

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    PG
  • TimmooreTimmoore Posts: 1,031
    edited 2009-08-23 19:00
    Have you got a list of the things you want? Then look at each, the CPU time each thing needs, the time accuracy, etc. You can work out how many cogs you will need. Many things dont need to be done that often so you can have the main loop go through each item and handle it without adding cogs

    Heres an example from one of my bots:

    main loop - 1 cog - does all main processing: gets A2D results - passes to IMU, gets IMU results updates pid, gets encoder results updates pids, gets pid results updates motors, selects between RC mode using vex receiver or autonomous, read compass and pass to IMU
    watchdog - 1 cog - checks to make sure system is running correctly and reboots sysem if not. Also polls vex receiver
    4 serial ports - 1 cog - debug port
    motor pwm - 1 cog - PWM generation for 4x h-bridge for 4 motors
    Quadrature encoder - 1 cog - getting encoder counts
    tv2543 a2d - 1 cog - 11 channel a2d for IMU (gyro/accelerometer
    imu - 1 cog - 6 axis imu
    vex - 0 cog - vex receiver - ctra on polling cog (watchdog)
    i2c - 0 cog - i2c driver
    compass - 0 cog - i2c cmps03
    pid - 0 cog
    timer - 0 cog - rtc - ctra and ctrb on calling thread (main)
    config - 0 cog - pin/i2c configuration
    floatmath - 0 cog
    floatstring - 0 cog - debug output

    I looked at the system
    pwm needs a cog for continous updating - may be possible to use counters with polling for small no of motors but I needed 4 (plus more for future)
    encoders needs a cog - for timing accuracy and speed of the pulses - may be possible to use counters with polling for small no of encoders
    I gave a cog to A2D - allows fast enough reading that I could low pass filter the sensors
    I gave a cog to the watchdog
    then the main cog was for decision making and moving info between the other cogs
    I gave a cog to the imu because it was slow, needed lots of CPU and I didn't want to slow main loop down
    Originally I had a cog for Vex receiver but looking at how often I had to call it (~every 0.5ms) I could do that on the watchdog cog using a counter

    I also looked at the future
    GPS - can share serial port with 4 port serial, other processing can be polled from main cog, so 0 cog
    camera - CMUcam uses serial port, other processing polled from main cog, so 0 cog
    pan/tilt for camera - motor pwm can also drive servos, motor pwm is written so if used more than once shares cog so I can drive 2 servos as well as 4 motors with 1 cog so no 0 cog

    The biggest bot I did uses 2 CPUs, one for sensors and one for everytime else. All the other times I used a prop. Camera processing is one of the most cpu intensive, the prop isn't that good for it because of the memory limitations.
  • P!-RoP!-Ro Posts: 1,189
    edited 2009-08-24 01:36
    I can try and explain. I have some equipment right now but I plan to add extensively to it later. So, because of this, I'll make two lists with what I have now and what I hope to have soon. Then, after all this, I will explain some of the tasks I wish to do.

    What I have currently:
    2 sonar sensors, one spanning 3 meters, the other 9
    a 2 axis accelerometer
    digital compass
    ir object detection for the front
    rpm detection
    lcd display
    keypad
    front steering (will need to control using pwm and input from a pot)
    brake motor, similar to what's above
    2 servos, one for sonar, one for the engine
    sd card for writing info on
    a vibration sensor I might use to tell if the terrain is rough
    a ir detector which will detect signals from a band I will use to let the robot know if I am near
    numerous leds to give messages out if need be

    What I hope to get soon:
    gps
    a 3 axis accelerometer
    8 pigment ir heat sensor to detect humans and animals
    uOLED screen
    rc receiver/transmitter
    2 sonar sensors with a range of 6 meters, one on each side of the 9 meter one in the front. The 3 meter might go in the back later once I get the robot set up to back up.
    3 additional servos, maybe a 4th one for the back sonar, added to the servos mentioned above
    All servos will be modified with an extra wire coming out to detect their exact positions.
    Far into the future maybe a camera or two (I'll only get a second one if the first works okay, but it may not be doable with the prop)
    Possibly a pan/tilt paintball gun on the front for some fun
    A hall effect sensor on the front and back wheels to detect true speed as well as to allow me to know if there is slippage
    back-up motor (have it, just have to figure out how to use it)
    And possibly even more as I go farther with this project

    Tasks:
    Create a map of a location and save the data by gps coordinates. Using trig on the prop (something I have never done before but know it is possible) data fed in by the sonar and ir sensors will be used to find the gps coordinates of all obstacles in the area, such as a tree, or a building. This information will be saved to an sd card. Every time the robot goes into one of these previously mapped areas it will use any new data and average it with the old data getting a more accurate positioning of the obstacle. Around these areas the propeller will also mark a risk zone, or an area where fluctuating gps coordinates could misplace the obstacle. In these areas, the robot will go slower and use it's sensors to make sure it knows the definite location of the object.

    Besides just using this mapped information to know appropriate speeds for different zones, the robot will also be able to use it to generate a path of which to follow, finding the easiest way possible from one location to the next. Once it has generated a map, it will save it to use multiple times. If, at some point it finds new information that can make this path even easier, it will modify the information to the new route.

    Safety measures:
    The robot will not only be able to detect information coming off an ir band all viewers in an area will have to wear, it will also have a 8 pigment ir sensor to detect the presence of people as it goes past. If it can not move out of the way of a person, it will be forced to stop.

    Besides just safety around other people, it will also be safe for different structures and other objects by having a built-in safety system to detect problems somewhere in the whole system. If a servo controlling the engine does not control it in the way expected to to a broken component or something similar, it will be set to instantly stop the robot. I may even set up a circuit separate of the rest of the robot made to take control if there is a problem with the electrical system.

    Just for fun:
    I hope to add a paintball turret controlled by rc signals along with the robot possibly sending low-quality images back to the controller allowing me and other users to see what is occurring without having to be in view of the robot. I also hope to be able to switch the robot from being autonomous to rc whenever I choose, selecting what tasks I wish for it to do as well as sending it instructions such as different gps coordinates to travel to. It will also let the robot be safer by allowing a take-over by a controller if things get out of hand.

    Future ideas:
    If I can figure out how to work a camera on the propeller I will use it to possibly detect obstacles using images, as well as to know how it should behave in different areas, such as a tall grass field, paved ground, rutty dirt path, and many other types of terrain.

    I will update this list if I come up with anything else.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    PG
  • TimmooreTimmoore Posts: 1,031
    edited 2009-08-24 02:17
    So now look at the devices and list how quickly you need it to respond - the sonars have X range, you are moving max speed of Y, therefore detect time must be < Z. Also how does each device work e.g. sonar tend to be analog, I2C or parallax ping style. You should be able to build a tree of the sensors, how often to check the sensors, what interfaces etc.
    Can you set it up so all the devices get polled in a loop putting there results in a big array. Then the main mapping code can use that to generate maps.
    I tend to find the majorty of sensors can be polled a few times a sec, so 1 loop that polls them all works. Then your main loop can do a poll all sensors, update map, decide what to do, repeat. The other thing you can use, is often sensors can be run at different rates e.g. you may have some that need to be 10/sec, some 2/sec, some once per sec. So the main poller should understand that and poll each sensor different times round the loop, i.e. have a loop counter that goes from 1 to 10, when the count gets to 10 reset to 1. When the count is 1 and 5 poll the sonars, count == 2 poll IR, count == 3 acclerometer, etc.
    If you want example code I have a lot that uses these types of techniques. One of the things I did is to feed the results of the sensors back to a PC and dispay them, the direction, tilt of the bot. A map of the thermal, ir ranger and ultrasonic rangers around the bot, etc. It was very useful to debug all the sensors and is still fun to drive the bot from the PC and get all the info about the bot.
  • P!-RoP!-Ro Posts: 1,189
    edited 2009-08-24 03:07
    It's a hard question to ask, especially since this will be the first robot I've ever worked with capable of going 30+ mph. I have some timing ideas going through my head right now, but I won't mention them since they will probably change a bit as I go through the possibilities. If you have some great code lying around that does this sort of thing go ahead and post it, I'm sure it will be very helpful even if I choose to do the task in a different way.

    Thanks for the help so far.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    PG
Sign In or Register to comment.