Verify no missing inputs? Topic is solved

Technical discussions around xCORE processors (e.g. General Purpose (L/G), xCORE-USB, xCORE-Analog, xCORE-XA).
Gothmag
XCore Addict
Posts: 129
Joined: Wed May 11, 2016 3:50 pm

Verify no missing inputs?

Postby Gothmag » Wed Jun 01, 2016 4:41 pm

I'm creating a robot that uses quadrature encoders on no less than 2 wheels I have 60 triggers on a 2.2" wheel, 1 rotation is a little over 34cm travel. The vehicle can travel around 20m/s. If I were to just increment a value I have no doubts it'd work, but I try to update localization and speed at the same time. This uses 2 doubles and 1 sin/cos call per a or b channel tick(high or low), and I record the times of a and b and use that to determine speed.

The sin/cos calls are run in a par block. I'm doing this on a startkit and a explorer kit. When I was using a 4 bit port it was less reliable than using the gpio library as input with events on the 4 bit port. Looking at the gpio library shows its not doing anything much different than I was. What this makes me worry about is missing quadrature edges as they're fairly important. So does anyone have any ideas? Or should I not be having an issue? I can provide more data or code later but don't have access to a pc now. On the explorerkit the quadrature signals are all on 1 bit ports, and I'm planning on dedicating one tile to localization and pathing stuff. I do have data logging so maybe my best bet is just drive in as straight a line as I can and compare the wheel locations or tick counts?
View Solution
henk
Respected Member
Posts: 346
Joined: Wed Jan 27, 2016 5:21 pm

Postby henk » Wed Jun 01, 2016 6:15 pm

Hi Gothmag,

If you use a port and a select, you will not miss inputs if the time taken for each case is short enough; before the next case is taken (you probably guessed this). A couple of thoughts:

1. Using the GPIO library may add some overheads, depending on what is and isn't inlined.

2. It would be worthwhile to quantify the time between events. 20 m/s = 60 revolutions per second = 3600 triggers per second = 300 us per trigger. How long do the sin and cos take? And you do run the par inside the select, or around it. At present par{} is optimised for functionality, not for running in straight-line code, i.e., it adds some overhead.

3. Is any debouncing required? In particular, is it possible that the it triggers three times in a row, i.e.,
Aup 300us Bup 300us Adown 300us Bdown 300us Aup 1us Adown 1us Aup 298us Bup... where A wiggles once too many; very quickly after any of the previous ones? This would mess up the above timings. You may account for this by doing a 'when pinsneq()'; that means you never miss anything.

4. Do you need double precision sin() and cos()? There are pretty good fast sin() and cos() fixed point implementations in the DSP library. They work on numbers with 8 bits before and 24 bits after the binary point. Ie a granularity of 5e-8. They are much faster than the double precision ones.

Using 1-bit ports should be fine too; just put both cases in a single select{}; you may need some debouncing in that case.

Cheers
Henk
Gothmag
XCore Addict
Posts: 129
Joined: Wed May 11, 2016 3:50 pm

Postby Gothmag » Wed Jun 01, 2016 6:40 pm

I know the gpio library has some overhead but since I was definitely missing triggers using the 4 bit port directly I tried using it and found it worked better. I may be able to switch to floats for localization but more precision is better so I'm trying to see if I can get it working with doubles if possible. The timing on the sin and cos are massively variable. I get best case timing of 17us or so but 340us worst case. The par for the sin and cos is in the case for the gpio event, just the two instructions. I'm also running many other threads on the processor but the quadrature handler has a dedicated core.

The quadrature sensors have built in hysteresis and based on testing with an oscilloscope debouncing isn't an issue. Also using somewhat strong pullups(1.2k) on the a, b trigger lines.

As long as the code completes in time for the next event though I shouldnt miss any then? On the startkit version this will possibly be an issue since two wheels are on one core with the gpio library overhead. The explorerkit version though has 1 core per wheel, making the timing less intensive. Maybe I'll switch to floats and fast sin cos for the startkit car. I'll also try checking the difference between using the sin/cos in par and not.
henk
Respected Member
Posts: 346
Joined: Wed Jan 27, 2016 5:21 pm

Postby henk » Wed Jun 01, 2016 7:17 pm

Sorry - I read your post the other way around! Quite surprising that the GPIO library works better than the select; I have no idea why.

There may be single precision versions of sin and cos that will be faster; but keep in mind that unless you need the dynamic range, the fixed point version may well get you better accuracy - it is using all 32 bits for the mantissa - not just 23 of them.

If you want to use floating point, I would outline the par - put the sin() and cos() functions in separate threads early on in the program; and then use a channel to send the values to them to perform the computation; that will remove the par overhead completely. The fixed point sin() is fast enough to not need a par.

If you split the quadrature encoder in two you will be less time sensitive; if that works. Whenever I write it I find it much easier to do it in one select (it is my favourite example to show people how a select statement works!).

Cheers,
Henk
Gothmag
XCore Addict
Posts: 129
Joined: Wed May 11, 2016 3:50 pm

Postby Gothmag » Wed Jun 01, 2016 8:03 pm

Yea it's pretty odd that I'm getting better accuracy with gpio. I was just masking the bits I needed and using like 1 bit within a pinsneq case but for some reason, maybe it's supposed to work this way, I would get the message and both the a and b triggers had changed values, even at very slow speeds where timing wasn't an issue.

I'll give the fixed point versions a shot and see how they affect timing and accuracy. I won't be splitting the handling of the quadrature signal though, just split left and right signals. On the startkit there werent enough 1 bit ports so put both sensors outputs on the 1 4bit. Thanks for the suggestions and info.
Gothmag
XCore Addict
Posts: 129
Joined: Wed May 11, 2016 3:50 pm

Postby Gothmag » Fri Jun 03, 2016 6:11 am

Just thought I'd update, by using all floats, and floating point trig functions I cut my worst case times to less than half(Worst was about 330us, not it's 140us). Somewhat expected considering there is no hardware support, and having sub-millimeter accuracy isn't that important even when odometry errors accumulate over 100 meters. Although I'm sure there is a scenario where I miss inputs anyway since I have 2 wheels running on 1 thread/core. Errors like that will be small enough that averaging the position of the wheels should take good enough care of it.

Who is online

Users browsing this forum: No registered users and 2 guests