How can I add a new message in the mavlink protocol? - c++

I'm new in Mavlink, I want to add a new message in the Mavlink protocol and send it each second periodically. How can I do it?

Here you can find detailed steps about how to add new message to mavlink protocol and how you handle it.
Ensure you have the latest ArduPilot code and Mavproxy installed.
Decide what type of message you want to add.
Add the new message definition to the common.xml or ardupilotmega.xml file in the mavlink submodule.
Add functions to the main vehicle code to handle sending or receiving the command.

It depends on what autopilot you are using. If you're using ardupilot then you would need to add a new xml message definition in ardupilot/modules/mavlink/message_definitions/v1.0/ardupilotmega.xml.
You can look at the other messages to see how it should be formatted. Just make sure you choose an id that is unused.
Next you need to decide how to put this in the code. You could place it in the data_stream_send task by adding the message id to, say, STREAM_EXTRA3. This will send your message as often as the other data is sent there. As part of that you will need to define the function to actually pack your data structure using the function generated by pymavgen, the message id and enumerations. This is what I have done in my own project for ASH_DATA. You can see the changes I've made in my repository for reference. Note that some of those include changes to incorporate reception of ash data on the pixhawk and adding the data to a log file.
Given that you want to run this once a second you may want to add to the one_second_loop task or create your own task that simply calls the try_send_message function using your new message id.
You will of course need to incorporate the new message in your gcs so you can actually receive it, but that's another matter.
Hopefully this can nudge others in the right direction who are trying to do the same.

Related

cfapi: CfDehydratePlaceholder seems to be stucked

My target is, that files can be hydrated or dehydrated on user request via the Explorer "free up space" or "Always keep on Device" ContextMenu entry. In case I create a new placeholder file that is dehydrated from the beginning, everything works and I can hydrate it via the callback mechanics. But the way around does not work for me. Inside of the Explorer the file will be marked as UnPinned and the file will be marked as syncing, but my application does not receive any callback from CF_CALLBACK_TYPE_NOTIFY_DEHYDRATE or CF_CALLBACK_TYPE_NOTIFY_DEHYDRATE_COMPLETION. Then I wanted to do it manually with CfDehydratePlaceholder, but exactly the same behaviour. Nothing happens and the file remains in the state, syncing. Even if I used CfSetInSyncState to set the state to CF_IN_SYNC_STATE_IN_SYNC it remains to be in the state syncing.
Now I wanted to implement a minimal example with the help of Cloud Mirror Example, but I realized it has the same behaviour. When I try to dehydrate a file again exactly the same happens there as well. From my perspective, it feels for me like cfapi expects an ack from the cloud service, which it never gets.
But in OneDrive everything works like expected. What I am missing? Did I have to set some specific settings?
I had a misunderstanding of the whole API and here is how I understand the API now, to help other people, who are struggling with it.
You have to register your sync root and connecting your app to it. In case of connecting it, you will receive a CF_CONNECTION_KEY, which is needed to communicate with the virtual filesystem. Then you can add extended attributes to all files inside of your sync root. The most important are custom attributes you can choose by yourself to identify the file object by your app if needed and then the PinState and SyncState. Mostly the SyncState don't have to be changed by the app, besides marking a file as synced after it was processed by the app. (you can do it at the moment you update your custom attributes) Because in case a file changed, the SyncState will automatically be changed. The PinState declares which final state a file should have. For example UNPINNED means, that the file should be dehydrated, and PINNED the opposite. It does not mean, that the file necessarily has already this state. My misunderstanding was, that I thought in case I unpinned a file, it will be automatically dehydrated. Or in case I pinned a placeholder I will receive a request via the callback function I mentioned in my question. But this is not the case. Your app needs to find out via a FileWatcher (i can recommend my own created FileWatcher project: https://github.com/neXenio/panoptes) that the file attribute of specific files was changed. Then your app has to process every step. Like already mentioned in case of dehydrating, the app needs to call CfDehydratePlaceholder. In case of hydrating, you need to open a transfer session via CfGetTransferKey and then hydrate (send the data to the empty file) via the method CfExecute, where you need the connection key and the transfer key. And that's are the basics. There is much more to tell about it, but I guess with this beginning, everybody can figure it out by himself.

How to call an exe on an insert event in a table

On an insert event in a table, i need to fetch some data in a file using C++ API and send that file to client.
So currently my plan is to Check the " After insert" event using a sql trigger and call the C++ exe from the trigger.
I found in many places that its not advisable to call an exe from a trigger. But i believe in my case it should not be a big issue as my exe is not going to update anything, rather it will just fetch some data and generate a pipe delimited file having those data.Please let me know if this has any limitations.
Question:
What are the steps i should follow to call an exe from a trigger?
If i call my exe from the trigger, should it cause any types of issues in database like database hang?
Note: A better approach comes to my mind is:
We have our own C++ APIs using which i can connect to Database.So i can put a logic in C++ which should have a daemon logic to check the table every time and generate the file once an insertion happens in table.But the problem here is , my client don't want to have a daemon process which needs constant monitoring and increase the maintenance work.They are suggesting to go with an approach where it should run the application only when the insertion event happens.
Please help me on this whether i should go for trigger approach to call the exe from there. Also please let me know for any better approach.
I think a better approach would be to use a DBMS_SCHEDULER call in the trigger to create or schedule a job that will invoke your external application. This way you will decouple your database operation from the external call and yet you will be able to trigger the program when necessary instead of polling the table.

formatting a FIX message to a c++ struct or classe

say I want to format my fix message received in a XML form ( not FIXML ! ) but kind of like the spec description, for example like that
<message name="Heartbeat" msgcat="admin" msgtype="0">
<field name="TestReqID" required="N" />
</message>
and in my output I need to have a c++ struct or a class called HeartbeatMsg whose attribute are its own fields.
So after parsing my XML file, I want to stock those messages parsed into an object that I can call later by a printer or formatting class that take my message object and write it into a file.
so I thought this message object that I want to instantiate maybe I can create it as a new class that inherit from the message class in the QuickFix library, so my question is :
could I do it? because I read the QuickFix message and it's loaded with functions that can be used for more than describing the message but also for extracting it, serializing it
from a stream input.
so although my need is far away from that, can I still use this classe for a simple formatting.
What you get from your XML can be parsed into a FIX object, using the Quickfix library. But it is going to be doing the work twice. 2 places when it can be done
When you receive and process your XML message to use, you can as a concurrent job create a FIX message using the Quickfix library. But that would surely slow down the processing of your original application.
When you process the XML message and convert it into a format your code understands, store that object you create and create a FIX message out of it as a side task totally independent of your original application. That way your original application runs as it is and it doesn't care about the FIX message creation. But you may have to copy your objects to a place from where the FIX message creation can be started.
Both require a combination of your original API and Quickfix library. So be careful when integrating them.

How to open source file in specific instance of Visual Studio (2008)

I have several instances of Visual Studio 2008 opened and I want to open a source file in a specific instance.
I plan to do this with Win32 API and something like ShellExecute(...), but I can't find solution yet.
Is there any way to do so? Any thoughts?
Unless the application opening the file (VS2008) has a message handler set up to initiate opening a file (not sure if it does or not; this would be the easiest method), you could probably simulate a drag-and-drop of the file to the application's client area (via message sending directly to the client window's message handler). You would need to get a handle to the client window of VS2008 for the instance you are sending the message to.
Don't know what the purpose would be, though. You can generally call up a new instance to open the file using ShellExecute(), but that wouldn't refer to a specific instance that is already running.
Another method you might consider is to hook VS2008's message handler for the main window, and log all messages sent relating to menu commands. You might be able to determine if there is a message event associated with opening a file. Figuring out the parameters sent to the WndProc() function would be another story. Hopefully it would be sent as a string pointer (for the filename) to lParam.
You could try using AutoHotKey. It's got a built-in scripting language and has various alternative ways of identifying which application to send its messages to.

Is a separate message file library for my native Win32 service necessary?

We've got an old legacy win32 service, developed with C++, and we've just recently noticed that when the service starts up and stops, there is an informational message in the event logs about our missing event descriptions. To be more precise, the message looks like this:
The description for Event ID 0 from source [application] cannot be
found. Either the component that raises this event is not installed on
your local computer or the installation is corrupted. You can install
or repair the component on the local computer.
So we understand what this means, basically we're missing a library which has a message table compiled into it. This way when the event ID for changing status (start/stop) arrives, it can look up the message and print it in the event logs.
The question is, for these universal messages (changing status etc) which pretty much every service is going to have, surely there are default message table that we can use, rather than having to go to the trouble of creating another project, just for this, adding registries and updating our installer.
Seems like a lot of hassle for something that should surely be a default somewhere? Like the standard win32 error messages?
I've created a number of managed services in the past, and I'm pretty sure we didn't need to do anything like this before!
So to wrap this up, I guess the answer is that the a new message table/file is always required, regardless (so no there are no default messages you can use), so I'll just have to chuck in a message table into my services resource file and add a registry entry to the installer.
Still find it baffling thought that every native service has it's own 'service has stopped/started' message...!
Thanks!