Welcome new user! You can search existing questions and answers without registering, but please register to post new questions and receive answers. Note that due to large amounts of spam attempts, your first three posts will be manually moderated, so please be patient.

static map access on jevois - error

0 votes

I have a new module that implements a global static map to save shared_ptr instances of a subcomponent, in order to access the class functions from free functions

In summary (pseudo-code):

class MAVLinkTest : public jevois::Module{
itsMAVLink = addSubComponent<MAVLink>("MAVLink", &MAVLink_data, MAVLink::Type_t::USB);
itsMAVLink->set_instance(itsMAVLink); //saves a copy of shared_ptr in the static map
}
process(){
auto m = MAVLink::get_instance(MAVLink::Type_t::USB); //retrieves a copy of the instance with matching type
m->somefunction();
}

Where the global static map is 

namespace  mavlink {
    static  std::map<MAVLink::Type_t, std::shared_ptr<MAVLink> > gMAVLink_instances;
}

The current code can be found in this fork - MAVLink branch. 

I was able to successfully run the code on ubuntu host and receive and send MAVLink messages, but I get an error when running it on jevois. The error occurs when I try to access the global static map to retrieve the instance. Could there be some differences in the compiler flags that changes the behavior of static global list/map access? I can't figure out how to debug it and step through with gdb on jevois so far. 

I'm able to access the class instance from within the module class (with itsMAVlink) but that doesn't solve my problem, since the mavlink API requires free functions that access the serial send and receive methods.

I'm open to suggestions on how to save the MAVLink instance somewhere and retrieve it in a free function based on some criteria I pass to getInstance function. 

Here is a question I posted regarding the implementation method. 

- Ali

asked Jun 23, 2017 in Programmer Questions by alsaibie (740 points)
edited Jun 23, 2017 by alsaibie

1 Answer

0 votes
I figured out the issue with accessing the shared ptr instance, I was checking if the shared_ptr_instance != nullptr, which works on the host but no on the platform. Instead I had to use !shared_ptr_instance (a bool operator) to check if the instance is valid. No I'm running into problems with the mavlink functions which is a separate issue now and I'll continue looking at.
answered Jun 23, 2017 by alsaibie (740 points)
Finally got MAVlink to work back and forth between host and platform as well QGroundControl, using serial-over-USB. The next step would be to test it on the hard serial. I believe I'm running into a buffer overrun issue, say I start streaming and sending serial characters but the received is busy or disconnected the program just hangs at write(), I'd like the program to dumb the buffer and continue its thing, I've added a flushout function (tcflush(itsDev, TCOFLUSH)) and tested calling it periodically but that didn't seem to help.

Any pointers on automatically draining the buffer if full? I'm using the Serial::write() to write characters out.
Indeed we have tried in the Serial class to not drop any data, and instead to throttle down until all the data can get through. I think if you do not want this feature maybe the best is to make your own version of the Serial class with a simple call to ::write() and no checking. Or just add a writeNoCheck() function to Serial and send us a pull request, we will integrate it. Just look at Serial::write() and only keep the call to ::write() in there. The problem with that is how will you get back in sync, i.e., if half of a message gets lost, how do you detect that?
That makes sense, I'll add a separate function. Now to sync there are two options, keep MAVLink in a separate thread, but have to make sure I don't lock a data mutex, or use the MAVLink API to check if data is received properly (say if not all parameters are received, request new transmission, and/or acknowledge receipt of message), which is how the proper MAVLink implementation is done (still learning as I go along). I will want to implement multiple threads in any case, will cross that bridge when I get there.
Is there a built-in way to pass camera control parameters from a module? Say I want to pass setcam gain from process(). I can add the camera controls as MAVLink parameters and they can be set using GCS. If not available, what's the safest way to do so?
oops, there isn't, same reason as for why you cannot mess with Engine's parameters: those controls should be under user control and not module writer control, to avoid surprises as to why some settings made by users end up having no effect.

You can write a file called script.cfg in the directory of your module, with any valid CLI commands in there. It will be run after your module is loaded and init()'ed. See the ObjectTracker in jevoisbase for an example. Let us know if it does not work, has not been thoroughly tested yet...

btw, this question would probably be more useful to others as a standalone question, for future reference.
...