uNav INS

I saw the CB.available as the flag? If a _QUE put one in ... then .events() processes it?

On Master's entry to .events() it could time check Slave ... process as needed ELSE Time check Master ... process if CB not empty?

Only want to do a single transfer per .event check - you can decide priority Master or Slave first?
 
no to have a single transmission of events we cant just throw a number at it, remember the 0xADD0 flag? its a t16 queue available flag, quantity unknown

we could slip in a, i dunno, 0xADB0 if the slave callback queue is empty, that should get the master to run 20 transmissions and the 21st transmission is a commence flag, no?
 
priority wouldnt matter, both flags will update to master from single event call, master can do all push/pulls it wants afterwards
 
details are yours ... I thought I had a usable high level understanding ... basically just take params and data from .transfer16() when comes in by _QUE and dispatch later when .events() is called?

For: aHRS.transfer16((uint16_t *)MST_PrintVals, sizeof(MST_PrintVals) / 2, 55, 1);
It goes out NOW.

For: aHRS.transfer16_QUE((uint16_t *)MST_PrintVals, sizeof(MST_PrintVals) / 2, 55, 1);
push that data to CB for master transmit later when .events() is called?
 
yes thats possible, but doing transfer16 or transfer16_QUE just seems like same, whether your transferring directly (now) or end of loop when events is called (scope exit?). for it to matter it would need to be based on bulk transfer of queues, which would give the slave lots more “processing time” in normal loop for queue completions, before it signals the master that theres nothing in queue. the processing signal from the master would be able to tell the slave to start only when its signalled, so while pop_front’ing your queue to SPI, it will deque lets say 12 items on queue, to the slave and send a signal to start, from a single event call. it wouldnt need extra ram because eact transaction is a queue transfer before the final transaction says go, but if Mike is getting 200micros im wondering how much faster you think this would improove, or if we think were doing it right, and it turns up wrong :p

or do you mean always dequeue every loop as long as the slave says “im all clear, feed me” a single queue item, and since events() runs in tight loop it will always get that “flag” every time, we wouldnt need a bulk transfer, which makes it easier, and allows the slave to say “ok go ahead im ready” signal so the f&f is transfered based on clear flag vs micros/time method?
 
like this:

events()
events()
events()
events() <—— slave slipped in a flag, master deques an item to slave from f&f queue
events()
events()
events()
.......
events()<—— slave slipped in a flag, master deques an item to slave from f&f queue
events()
events() <—— slave slipped in a flag, master deques an item to slave from f&f queue
etc

this would mean were not spacing it ourselves or by calculating time gaps, but, were relying on a ready state to push it


is that what you mean?

we could also use the same “flag” for both instead of slipping in 0xADD0 (slave has queues to send to master) we could specify 0xADD1 means theres no STM queues but the callback queue is empty, and 0xADD2 to let master know theres both no more callbacks in queue and ready for f&f processing
 
I boosted up to 250 micros just to be save but I am also just using 4 buffers instead of the 8 that I first used - wanted to see what happened. Thinking about my poor little T3.1.
 
yes thats possible, but doing transfer16 or transfer16_QUE just seems like same, whether your transferring directly (now) or end of loop when events is called (scope exit?). for it to matter it would need to be based on bulk transfer of queues, which would give the slave lots more “processing time” in normal loop for queue completions, before it signals the master that theres nothing in queue. the processing signal from the master would be able to tell the slave to start only when its signalled, so while pop_front’ing your queue to SPI, it will deque lets say 12 items on queue, to the slave and send a signal to start, from a single event call. it wouldnt need extra ram because eact transaction is a queue transfer before the final transaction says go, but if Mike is getting 200micros im wondering how much faster you think this would improove, or if we think were doing it right, and it turns up wrong :p

or do you mean always dequeue every loop as long as the slave says “im all clear, feed me” a single queue item, and since events() runs in tight loop it will always get that “flag” every time, we wouldnt need a bulk transfer, which makes it easier, and allows the slave to say “ok go ahead im ready” signal so the f&f is transfered based on clear flag vs micros/time method?

The goal is for it to be the same nothing more complex - just a way to delay processing.

In the heat of the moment one or more events can be queued for sending later - in this case after some delay from the last transaction. It is overwhelming the slave to get the F&F that tells it to USB Print 853 characters - and then immediately have the Slave_isr trigger to get another event to process while that data is still on the way out.

As it is Mike wants to send two messages - they are time stamped as long as they are delivered it doesn't have to be now. But to get both to be successfully received he has to hardcode delayMicroseconds(250). That is not productive and interrupts the code flow.

If one is sent and the other put in _QUE() - other processing can happen as needed on Master and Slave - and then when .events() is hit ideally the Slave will be done with the first and ready for the second. The only adjustment that might be needed would to have transfer16() mark the .events() timer for Master as '0' so it delays the time it needs before another message is sent.
 
on post 381 i think thats the plan where the slave decides when to pull the master queue based on "nothing to do", the master wouldnt send it unless the slave has a persistant flag set in event() polling, in which case, the master would deque and send immediately ONE queue item to the slave, without millis() checks needed... then your tight loop which has no delays runs super fast and continues to poll events(), all of a sudden, it sees the flag set, so master dequeues one item again and transmits it,

without the millis() time check, the processing time is based PER packet, meaning, it could take 5uS to process, or 20uS to process, thats the time that the flag is set by the slave after completion, so that 20uS timeframe, by the time master hits events(), it captures the flag and immediately dequeues an item, I think this may be the fastest possible way and give the loop its own processing time as well

everytime the master sends from deque it clears the flag, when the slave is done, it sets the flag
this wouldnt "delay" processing, it would take advantage of that end of processing to immediately run another F&F, no delays whatsoever betweeen master and slave
This would shave alot more than just 200uS that Mike is currently doing, because if one F&F Q takes 5uS to complete, but the 2nd takes 10uS, and the 3rd takes 3uS, thats 18uS total time without any delays (or gaps) for 3 F&F's processed

is this correct?
 
I'm not following the complexity in #381 - of the Slave getting involved. When the Master has a message with .transfer16 or _QUE'd it should send it. I only saw .events() as an existing way to trigger the _QUE to get empty. The events sending - for Slave has a built in Timer to prevent over activity - with a similar timer since last Master send it could prevent the flooding that Mike has run into.

If I were to have to do it in user code I'd just create a local CB object - push one in during the activity - then at a handy time just pop them off and do the .transfer16 one per loop at a maximum rate controlled as needed.

I found out why I thought I didn't have the Teensy RTC running as I was not seeing the LED qBlink ... pinMode(LED_BUILTIN, OUTPUT);

I need to get back to that - though now the day is gone and supper time is here.
 
so you still prefer a delay gap between transfers than synchronous processing since events is called every loop cycle? this wont overload the slave at all, neither would it cause the slave to sit there for the remaining microseconds before master decides when to deque via a timer

the operation of slave messages is different, its pulling out in 100ms interval checks i think, im not at pc now to recollect, but who knows that could be a waste of ~80uS gap of doing nothing, just saying :) even that one could set a flag so the gap would be ready to be filled without the use of that timer
 
I think so - since loop() runs idle between device input getting the current code path returned from cleanly makes sure that keeps flowing. For now the simplest thing could help not hiding the delay() in the code. The main goal is keeping the Master free to do its task - and get the message delivered for the slave to process when can be responded to. In this case it isn't time critical.

The only way this wouldn't help is if the code path gets back to loop() and hits .event() with no delay - so having the .transfer16 reset the time since last transfer so calling .events(1) would wait at least 1ms before sending.
 
While for uNavINS sending 2 messages may or may not be necessary I am thinking of the case where I have this on rover or quad. In this case someone will probably want to implement what they call MAVLINK. This is a messaging system that sends different parameters for the different systems on a quad or rover for monitoring. That's a couple reasons why I am interested in sending multiple messages. I am looking at this as a test bed for not only KF but for what we can do with SPI_MSTransfer. Wait till I try sending data over ESP, that's coming next.
 
ok i think i understand, but that still creates a gap of slave doing nothing, im pretty sure the delay() in events was added to not cause blasts if there wernt any queues on the slave, it can be same for master but you have the same problem, youll do your loops at 1ms dequeue rates if a flag was set, but during that ~950uS gap the slave is possibly doing nothing at all
the only reason why delaying events was because of the f&fs and events and slave queues happening at same time, however this causes loss of slave time workload to do as well, if we go with a single event call for event queues this would systematically make it do one thing at a time without gaps insted of 2-3 read/writes at same time with no delays, which is why delay in loop fixed that issue, and delay for slave transfers actually slowed down the receiving rates

im pretty sure you can achieve maximum performance based on completion time, all methods capture the “status” code
so youd know what to do automatically in a decent amount of time without the loss of the remaining timer/delay while the slave “waits for you” to continue....
 
we wouldnt need to hide delay, but we could try the back to back method with the transferQ to see results, every uS counts, lets not keep the slave doing nothing during that time..
remember when we never called events and we just fired single f&f over tight loops at 0ms? that was considered back to back and was able to keep up because im pretty sure it still was fast to complete the processing, adding events() etc cause more isr fires and less loop() processing time...

all design ideas need research :)
 
tonton81: Better to have the Slave doing nothing - that trying to do two things at once and failing, it is the Master that needs to conserve time dealing with critical events in this case. If it can be refined later that is cool - but seeing this resolve it would add great possibilities. If the Master gets free time and messages can be handled fast it can :: while ( x.events(0) ); and be done with them- assuming events returns T|F based on something to do?

I made some signs of progress. To check my logic I record micros() when I record ARM_DWT_CYCCNT for ccPartSec().

Shown here the ccPartSec() values to 100,000,000 resolution are compared to the micros() [ shown following with 'm:#' ] captured at the same time.

-----Loop#:371563 IMU#:501 >> 1Sec:100059680 >> 1Sec m:1000596 >> IMUcc:96240 m:962 GPScc:289410 m:2894
#12419 @8:27.27_308830 [fix:3 #:14 GPScc:289410 m:2894 >> cctAv:179999714
#12420 @8:27.27_200308906 [fix:3 #:14 GPScc:218352 m:2183 >> cctAv:179999714
#12421 @8:27.27_400308983 [fix:3 #:14 GPScc:235840 m:2358 >> cctAv:179999714
#12422 @8:27.27_600309059 [fix:3 #:14 GPScc:288496 m:2885 >> cctAv:179999714
#12423 @8:27.27_800309135 [fix:3 #:14 GPScc:284448 m:2844 >> cctAv:179999712

So far I have not changed anything - except to enable RTC_isr and also the GPS_Serial_RX_isr again. The GPScc numbers are diff from time of Rx_isr until transmit completed and arrive here in debugGPS().

The IMU values are just the LAST IMU_isr() recorded - but this is during GPS complete report so just for fun.

The 1Sec is just the time between last entry when GPS second text changed. - Just making sure the 1 second RTC pulse was scaling the CPU cycle counter properly.

The cctAv is just CycleCounts per RTC_isr() - Averaged from a 4 entry uint32_t CB I push the new values into and then call CB.mean() to get that average - shown for a 180 MHz T_3.6.

So with some code in place - but nothing changed - I could post an update if others need to make changes and minimize DIFFS later?
 
Impressive Tim. Thanks to tonton81: I got ACK packets working, as a test with the program :). Progress :)
 
Mike,
you mentioned MAVLINK a few posts back. I was thinking along similar lines. Would be neat to be able to push a nav (RTK eventually) solution back via MAVLINK to a quad-copter operator in real-time.

I've just left uNavINS running for many hours now and it just plugs along fine. Weather not been great, so haven't got my re-calibration testing done yet.

Don
 
Never really used MAVLINK myself. I know there are Arduino plugins for MAVLINK but never tried it. Just have to figure out a way to send the data - probably as a UDP or MQTT packet to an ESP :)

Glad its running ok. Now you can do the analysis and see if its good to go... :)

EDIT: if you are interested you can check this out - old lib - https://github.com/alaney/arduino-mavlink
 
I managed to add the scrollbars for the add chart and configure chart panels so at least you will be able to see all the checkboxes. There are a couple of things with the version I was working - its still in development - resize, move are just place holders for now, and the grid on setup isn't shown. The new version is setup that way intentional. The idea was to make the number of boxes you get changes as you change the size of the Tviewer window. They do show when you draw the charts. There is also a new feature that allows you to change the default size of the chart so when you click to draw it draws it to that size.
 
Mike, sounds cool. Please let me know when you do a release!

I'm still planning to build that interface to allow for changing of Q and R parameters on the fly. Hoping to get to that next week sometime. I need to study the formulation of Q in this version of uNavINS a bit more, as (I think) it really only allows uncertainty inserted via accel and gyro terms in the Rw matrix. So I'm curious to see if that folds back into Lat Lon Alt, and if so how. There are a number of different ways to build Q, so I might look at alternatives as well. Is great to see uNavINS running, and being able to stream the internal EKF parms!!

Don
 
Update: I think I'm doing good work - and AFAIK this Post .vs. Post compare is apples .vs. apples { all compile OPT and hardware the same } - nothing changed but adding timing code - not done yet - I trap the _isr() and record GPS and IMU time there - but have not replaced micros() for dt as it was.

>> Except TViewer is only running 5 Hz? When did this code come in? Why does it look FUNNY?
A propFlag is set and not used and then Filter.getekfPropFlag() ends up being called twice?
Code:
[COLOR="#FF0000"]      //if(sincePrint >= printRate){[/COLOR]
      propFlag = Filter.getekfPropFlag();
      if (Filter.getekfPropFlag()) {

This shows free loop counts Jumping 100K - the above code must have been what I got as I didn't get fresh since I added IMUcc on output in these posts::
Post #333 ::
-----Loop#:371358 IMU#:501| IMUcc:961 GPScc:3109
Post #391 ::
-----Loop#:371563 IMU#:501 >> 1Sec:100059680 >> 1Sec m:1000596 >> IMUcc:96240 m:962 GPScc:289410 m:2894
This Post ::
-----Loop#:471685 IMU#:500 >> 1Sec:99907512 >> 1Sec m:999073 >> IMUcc:125773 m:1257
<EDIT> Post 398 :: // Another BUMP :: a better way to detect IMU loss - if 3 GPS updates come in before a new IMU update the warning is triggered. ( can adjust to 1 - but this was easy to limit spastic printing )
-----Loop#:526566 IMU#:500 >> 1Sec:99968896 >> 1Sec m:999687 >> IMUcc:179417 m:1793

<note:> free running loop() # is just a simple metric - a simple change can alter it wildly - though it did show when GetSeconds() was in a bad place.

<nearly> Current code - should work unchanged since I didn't replace with _isr() timestamps anywhere yet:: View attachment TV_Layout_CFVer8x.zip
The timestamps change should be straightforward replacing micros()? but it is 4am ... Anyone waiting can try this - further diffs should be localized.

What I did do {showing the BUMP up in loop# - offsetting debug code duplicating micros() } is summarized here:
Code:
// float rtcOffset, rtcTime, newIMUDataTimer;  << All use and calc of these is gone :: DrtcTime propagates to TVIewer item #1
double DrtcTime;  // using DOUBLE rtcTime !!!  Will go over 12 digits in 11.5740625 days

// ...  the rtcTime was calc'd each LOOP() - even when no newIMUData
[B]// AFAIK rtcTime has NO USE except to timestamp the TViewer messages ??[/B]
// The GetSeconds returning a DOUBLE does DOUBLE divide and before I moved it the Loop# showed DROP to about 28K

    if (newIMUData == 1) {
  //Define RTC time for this iterationrt
  // rtcTime = (float) micros() / 1000000.0 - rtcOffset;
  DrtcTime = GetSeconds();

613.554565, 51.600395,156.916229,-131.070587, 60.584602, 48.214375,-122.450424, 33.148785, 0.673606, 0.812074, 0.095517, -0.095517, 1.000000, -1.000000, 0.516288, 0.563065, 0.113576, -0.113576, 1.000000, -1.000000, 0.399406, 0.556858, 0.169374, -0.169374, 3.000000, -3.000000, -0.001327, -0.004390, 0.074917, -0.074917, 0.050000, -0.050000, 0.048617, -0.000157, 0.095292, -0.095292, 0.050000, -0.050000, -0.010416, -0.005901, 0.017864, -0.017864, 0.050000, -0.050000, -0.001317, 0.000028, 0.001644, -0.001644, 0.020000, -0.020000, -0.001968, 0.000037, 0.003221, -0.003221, 0.020000, -0.020000, -0.000359, 0.000008, 0.001685, -0.001685, 0.020000, -0.020000, 0.165158, 0.165172, 0.287453, 0.049696, 0.049704, 0.049694, 0.039087, 0.034294, 0.043882, 0.087749, 0.090014, 0.093987, 0.008023, 0.007988, 0.008065,
613.754333, 51.702412,156.595322,-131.673233, 59.981953, 48.214375,-122.450424, 33.155361, 0.650443, 0.801442, 0.093969, -0.093969, 1.000000, -1.000000, 0.451289, 0.566312, 0.108746, -0.108746, 1.000000, -1.000000, 0.423130, 0.538847, 0.150996, -0.150996, 3.000000, -3.000000, -0.003024, -0.006944, 0.073420, -0.073420, 0.050000, -0.050000, -0.144285, -0.003187, 0.098240, -0.098240, 0.050000, -0.050000, 0.008807, -0.005616, 0.018022, -0.018022, 0.050000, -0.050000, 0.000216, 0.000051, 0.001641, -0.001641, 0.020000, -0.020000, 0.002018, 0.000077, 0.003237, -0.003237, 0.020000, -0.020000, 0.001375, 0.000019, 0.001693, -0.001693, 0.020000, -0.020000, 0.165149, 0.165164, 0.287448, 0.049696, 0.049704, 0.049694, 0.039078, 0.034375, 0.043821, 0.087749, 0.090014, 0.093988, 0.008023, 0.007988, 0.008064,
613.954102, 51.716579,156.123795,-132.152344, 59.502842, 48.214375,-122.450424, 33.159512, 0.662331, 0.791049, 0.090318, -0.090318, 1.000000, -1.000000, 0.457194, 0.568137, 0.106384, -0.106384, 1.000000, -1.000000, 0.449018, 0.522751, 0.130927, -0.130927, 3.000000, -3.000000, 0.026914, -0.007643, 0.072986, -0.072986, 0.050000, -0.050000, -0.056840, -0.009182, 0.095437, -0.095437, 0.050000, -0.050000, 0.013813, -0.004791, 0.018287, -0.018287, 0.050000, -0.050000, 0.001433, 0.000166, 0.001604, -0.001604, 0.020000, -0.020000, 0.005577, 0.000384, 0.003278, -0.003278, 0.020000, -0.020000, 0.003099, 0.000156, 0.001759, -0.001759, 0.020000, -0.020000, 0.165141, 0.165156, 0.287443, 0.049696, 0.049704, 0.049694, 0.039001, 0.034597, 0.043650, 0.087749, 0.090013, 0.093988, 0.008023, 0.007990, 0.008063,
 
Last edited:
I saw what the other day when I was looking at the code to change the output rate. That came in with the last released version that Don put up I think.

Nice work Don - can't wait to give it a try and see what happens. Probably later today :)
 
I saw what the other day when I was looking at the code to change the output rate. That came in with the last released version that Don put up I think.

Good to know - Surprised it took me this long to notice - that was the last code I got - but I wasn't watching the SPI_MST output as much as the Master Debug. If I stop typing to sleep I might be done shortly afternoon . . .
 
Back
Top