In view of Corvus Corax multicore experiments I took a look at UAVObjEvent.
typedef struct {
UAVObjHandle obj;
uint16_t instId;
UAVObjEventType event;
} UAVObjEvent;
What is the instId? (Yes I understand it stand for instance ID but what instance are we talking here?)
Shouldn't a ID of the module that "triggers" the event be present? Could be very useful when doing more advanced things like multicore, rendundency and multiple telemetry connections. Or is the increased overhead to much? I'm guessing the core team already has discussed this since it is a basic functionality in most event driven systems?
UAVObjEvent
Started by Malx, Oct 21 2011 11:11 AM
5 replies to this topic
#1
Posted 21 October 2011 - 11:11 AM
#2
Posted 21 October 2011 - 04:06 PM
Instance ID is because we can have multiple instances of the same data. For example waypoints or the "AccessoryDesired" object. As for a source ID I'd rather not add that until we have a use case. We're trying to watch memory on CC and that would right now just be empty memory as we don't use it. However it could be valid in the future.
It ties into a more general problem of UAVObject writing. Our basic philosophy is that only one module should be writing to an object and it doesn't really matter who. That information should be equally valid in either case - if this is not so then you should have two different objects to indicate that. However in some cases you want do swap the source (for example sometimes ActuatorDesired comes from manual control and sometimes from stabilization) and we don't have a mechanism in place right now for "locking" an object when a module wants to use it.
It ties into a more general problem of UAVObject writing. Our basic philosophy is that only one module should be writing to an object and it doesn't really matter who. That information should be equally valid in either case - if this is not so then you should have two different objects to indicate that. However in some cases you want do swap the source (for example sometimes ActuatorDesired comes from manual control and sometimes from stabilization) and we don't have a mechanism in place right now for "locking" an object when a module wants to use it.
#3
Posted 21 October 2011 - 06:49 PM
The "events" are currently not being shared between modules, and cannot propagate between nodes of a multi-core system either. They are always in respect to an event queue.
A module opens a new event queue for a certain purpose. With that queue it can do the following:
1. Get notified at certain time intervals (with an "event" as set when registering the timer, and a certain period)
2. For a certain UAVObject, get notified when a certain event happens. (in 99.5% thats EV_ALL_UPDATES which means "get me notified when the object changes" - UAVObjects are supposed to have only one datasource at any given time, to prevent conflicts, so you do not need to know the source so far)
3. For a certain UAVObject, get notified at certain time intervals (with an "event" as set when registering the timer, the object, when registering the timer, and a certain period)
This is only used in telemetry style modules which handle a lot or even all UAVObjects, and need to keep timers on a per-object basis.
When the event gets triggered, it is given to the queue listener (or the callback)
There are two mechanisms: callbacks are shot functions that get directly called by the event system, when such an event happens. They get notified INSTANTLY but they delay the event system, so they can't do any IO or any other slow things.
Queue listeners are generic threads that listen on an event queue on their own time, and act on new events whenever the CPU gives them time. (so with a short delay usually) Both get notified of the event triggered, which also includes object and instance.
HOWEVER, you can not listen for just one instance of an object, you will always get notified on all updates of any instance, and then have to find out if the one triggered is the one you want.
the source of the event (who caused the object to update) is supposed to be implicit. every UAVObject has a unique source which is supposed to set it.
For example AttitudeActual is set by Attitude (in CC) respectively AHRSComms (INSComms) on the PRO.
On a linked node it would therefore be set by UAVLinkBus, after the object had been updated on the other node and traveled there
A module opens a new event queue for a certain purpose. With that queue it can do the following:
1. Get notified at certain time intervals (with an "event" as set when registering the timer, and a certain period)
2. For a certain UAVObject, get notified when a certain event happens. (in 99.5% thats EV_ALL_UPDATES which means "get me notified when the object changes" - UAVObjects are supposed to have only one datasource at any given time, to prevent conflicts, so you do not need to know the source so far)
3. For a certain UAVObject, get notified at certain time intervals (with an "event" as set when registering the timer, the object, when registering the timer, and a certain period)
This is only used in telemetry style modules which handle a lot or even all UAVObjects, and need to keep timers on a per-object basis.
When the event gets triggered, it is given to the queue listener (or the callback)
There are two mechanisms: callbacks are shot functions that get directly called by the event system, when such an event happens. They get notified INSTANTLY but they delay the event system, so they can't do any IO or any other slow things.
Queue listeners are generic threads that listen on an event queue on their own time, and act on new events whenever the CPU gives them time. (so with a short delay usually) Both get notified of the event triggered, which also includes object and instance.
HOWEVER, you can not listen for just one instance of an object, you will always get notified on all updates of any instance, and then have to find out if the one triggered is the one you want.
the source of the event (who caused the object to update) is supposed to be implicit. every UAVObject has a unique source which is supposed to set it.
For example AttitudeActual is set by Attitude (in CC) respectively AHRSComms (INSComms) on the PRO.
On a linked node it would therefore be set by UAVLinkBus, after the object had been updated on the other node and traveled there
#4
Posted 21 October 2011 - 08:10 PM
peabody124, on 21 October 2011 - 04:06 PM, said:
We're trying to watch memory on CC and that would right now just be empty memory as we don't use it. However it could be valid in the future.
peabody124, on 21 October 2011 - 04:06 PM, said:
It ties into a more general problem of UAVObject writing. Our basic philosophy is that only one module should be writing to an object and it doesn't really matter who.
Corvus Corax, on 21 October 2011 - 06:49 PM, said:
The "events" are currently not being shared between modules, and cannot propagate between nodes of a multi-core system either. They are always in respect to an event queue.
I do understand that events are bound to the cpu/mcu they are triggered on. (Whether they are bound to the core is probably more a question for the OS)
Thanks for the other explanation about the events. That confirms what I thought about the system. The only problem I see is the "only one module updates an object". While it is a quite smart and normally a true situation even in a distributed system it gets into problem when you want flexibility. What happen if you want to have dual links? Are you gonna introduce a EV_SYNCED2 event? Of course you don't have to if you hardcodes which modules are runned on which nodes and only communicate the affected objects one-way...
In the end I only wanted to raise the question. It might be the best solution to keep it as it is for the moment. Especially with CC being so tight with memory.
#5
Posted 21 October 2011 - 08:20 PM
Malx, on 21 October 2011 - 08:10 PM, said:
Thanks for the other explanation about the events. That confirms what I thought about the system. The only problem I see is the "only one module updates an object". While it is a quite smart and normally a true situation even in a distributed system it gets into problem when you want flexibility. What happen if you want to have dual links? Are you gonna introduce a EV_SYNCED2 event? Of course you don't have to if you hardcodes which modules are runned on which nodes and only communicate the affected objects one-way...
Yes I would probably go towards multiple objects or assigning the two sources different instance IDs. If you really have two different sources clobbering the same object over each other, I'd say that is flawed by design.
The callback problem Corvus is talking about is similar to what is done on the INS/MB SPI link where objects are registered to be sync'd over the SPI bus. The comms module on the OP side subscribes to all the registered objects queues and when they are updated it sets a dirty flag. On the next transfer it sends the highest priority dirty object over to the INS. Similarly on the INS side a write to an object sets it's dirty flag and then it is sent over to OP. We actually have same issue because when that object is received on OP and unpacked it marks it dirty on the OP side and sends it back over. This doesn't matter in this case though because that direction doesn't have a lot of important messages.
#6
Posted 21 October 2011 - 08:42 PM
peabody124, on 21 October 2011 - 08:20 PM, said:
If you really have two different sources clobbering the same object over each other, I'd say that is flawed by design.
(Which probably only applies to "communication" modules.)
Dual sources was not the problem in Corvus distributed computing since still only one module is writing to each object. The problem is that the link module doesn't know on which node a certain module is running on so it sends everything back and forth. (which through events goes into a back-forth loop if the module is subscribing to the same event its sending)
I thought the communication module between OP/INS looked different on both sides so it just sends the right objects in one-way? I need to take a look there



Sweden
United States
Germany







