Sending Custom Mavlink Commands

Hello

I am attempting to send custom mavlink commands and data to a camera that is able to receive Mavlink data but I am having some trouble with the Arduino code. I installed the mavlink library, and have begun to attempt to modify code from here Arduino Mega ADK interfacing with Pixhawk autopilot - Project Guidance - Arduino Forum to suit my specific application. The problem I am having is that the code will not compile. I get "'GLOBAL_POSITION_INT' was not declared in this scope", however I thought that I was declaring it using the statement " uint16_t msg = GLOBAL_POSITION_INT;" but that is specifically where the compiler gets hung up.

I have looked through the original code and I cannot find anywhere that the commands are declared other than through the statement I referenced above ^^

Any help would be appreciated

//Code originally written by "hadogr" from Arduino Forums

//include the mavlink library
#include "mavlink.h"
//Baudrate
int bitRate = 57600;


void setup() {
  
  Serial.begin(bitRate);
}

void loop() {

 command_heartbeat();
 command_location(52.464217,-1.280222, 200);
}

void command_location(int32_t lat, int32_t lon, int32_t alt) {

  //TARGET DRONE
  uint8_t _target_system = 1; // Target drone id
  uint8_t _target_component = 100; // component id set to 100 for FLIR cameras

  uint16_t seq = 0; // Sequence is always set to 0
  uint8_t frame = MAV_FRAME_GLOBAL; // Set target frame to global default
  uint16_t command = GLOBAL_POSITION_INT; // Specific command for Duo
  uint8_t current = 2; // Guided mode waypoint
  uint8_t autocontinue = 0; // Always 0
  uint32_t upTime = 0; //time since system boot, ignored by camera
  int16_t velx = 1; //x speed
  int16_t vely = 1; //y speed
  int16_t velz = 1; //z speed
  uint16_t heading = 180; //heading


  // Initialize the required buffers
  mavlink_message_t msg;
  uint8_t buf[MAVLINK_MAX_PACKET_LEN];

  // Pack the message
  mavlink_msg_mission_item_pack(1,1, &msg, _target_system, _target_component, seq, frame, command, current, autocontinue, upTime, lat, lon, alt, alt, velx, vely, velz, heading);

  // Copy the message to the send buffer
  uint16_t len = mavlink_msg_to_send_buffer(buf, &msg);
  // Send the message (.write sends as bytes) 
  delay(1000);
  Serial.write(buf, len);
}

/************************************************************
* @brief Sends a heartbeat message every second.
* @param NONE
* @return void
*************************************************************/

void command_heartbeat() {

  //< ID 1 for this system
  int sysid = 1;                   
  //< The component sending the message.
  int compid = MAV_COMP_ID_MISSIONPLANNER;    
  
  // Define the system type, in this case ground control station
  uint8_t system_type = MAV_TYPE_GCS;
  uint8_t autopilot_type = MAV_AUTOPILOT_INVALID;
  
  uint8_t system_mode = 0; 
  uint32_t custom_mode = 0;                
  uint8_t system_state = 0;
  
  // Initialize the required buffers
  mavlink_message_t msg;
  uint8_t buf[MAVLINK_MAX_PACKET_LEN];
  
  // Pack the message
  mavlink_msg_heartbeat_pack(sysid,compid, &msg, system_type, autopilot_type, system_mode, custom_mode, system_state);
  
  // Copy the message to the send buffer
  uint16_t len = mavlink_msg_to_send_buffer(buf, &msg);
  
  // Send the message 
  delay(1000);
  Serial.write(buf, len);
}

/************************************************************
* @brief Sends a waypoint command
* @param NONE
* @return void
*************************************************************/

void command_waypoint() {

  //TARGET DRONE
  uint8_t _target_system = 1; // Target drone id
  uint8_t _target_component = 0; // Target component, 0 = all

  uint16_t seq = 0; // Sequence is always set to 0
  uint8_t frame = MAV_FRAME_GLOBAL; // Set target frame to global default
  uint16_t command = MAV_CMD_NAV_WAYPOINT; // Specific command for PX4 
  uint8_t current = 2; // Guided mode waypoint
  uint8_t autocontinue = 0; // Always 0
  float param1 = 0; // Loiter time
  float param2 = 1; // Acceptable range from target - radius in meters
  float param3 = 0; // Pass through waypoint
  float param4 = 0; // Desired yaw angle
  float x = 52.464217; // Latitude - degrees
  float y = -1.280222; // Longitude - degrees
  float z = 200; // Altitude - meters

  // Initialize the required buffers
  mavlink_message_t msg;
  uint8_t buf[MAVLINK_MAX_PACKET_LEN];

  // Pack the message
  mavlink_msg_mission_item_pack(1,1, &msg, _target_system, _target_component, seq, frame, command, current, autocontinue, param1, param2, param3, param4, x, y, z);

  // Copy the message to the send buffer
  uint16_t len = mavlink_msg_to_send_buffer(buf, &msg);
  // Send the message (.write sends as bytes) 
  delay(1000);
  Serial.write(buf, len);
}

Hello

I am attempting to send custom mavlink commands and data to a camera that is able to receive Mavlink data but I am having some trouble with the Arduino code. I installed the mavlink library, and have begun to attempt to modify code from here Arduino Mega ADK interfacing with Pixhawk autopilot - Project Guidance - Arduino Forum to suit my specific application. The problem I am having is that the code will not compile. I get "'GLOBAL_POSITION_INT' was not declared in this scope", however I thought that I was declaring it using the statement " uint16_t msg = GLOBAL_POSITION_INT;" but that is specifically where the compiler gets hung up.

I have looked through the original code and I cannot find anywhere that the commands are declared other than through the statement I referenced above ^^

Any help would be appreciated

//Code originally written by "hadogr" from Arduino Forums

//include the mavlink library
#include "mavlink.h"
//Baudrate
int bitRate = 57600;


void setup() {
  
  Serial.begin(bitRate);
}

void loop() {

 command_heartbeat();
 command_location(52.464217,-1.280222, 200);
}

void command_location(int32_t lat, int32_t lon, int32_t alt) {

  //TARGET DRONE
  uint8_t _target_system = 1; // Target drone id
  uint8_t _target_component = 100; // component id set to 100 for FLIR cameras

  uint16_t seq = 0; // Sequence is always set to 0
  uint8_t frame = MAV_FRAME_GLOBAL; // Set target frame to global default
  uint16_t command = GLOBAL_POSITION_INT; // Specific command for Duo
  uint8_t current = 2; // Guided mode waypoint
  uint8_t autocontinue = 0; // Always 0
  uint32_t upTime = 0; //time since system boot, ignored by camera
  int16_t velx = 1; //x speed
  int16_t vely = 1; //y speed
  int16_t velz = 1; //z speed
  uint16_t heading = 180; //heading


  // Initialize the required buffers
  mavlink_message_t msg;
  uint8_t buf[MAVLINK_MAX_PACKET_LEN];

  // Pack the message
  mavlink_msg_mission_item_pack(1,1, &msg, _target_system, _target_component, seq, frame, command, current, autocontinue, upTime, lat, lon, alt, alt, velx, vely, velz, heading);

  // Copy the message to the send buffer
  uint16_t len = mavlink_msg_to_send_buffer(buf, &msg);
  // Send the message (.write sends as bytes) 
  delay(1000);
  Serial.write(buf, len);
}

/************************************************************
* @brief Sends a heartbeat message every second.
* @param NONE
* @return void
*************************************************************/

void command_heartbeat() {

  //< ID 1 for this system
  int sysid = 1;                   
  //< The component sending the message.
  int compid = MAV_COMP_ID_MISSIONPLANNER;    
  
  // Define the system type, in this case ground control station
  uint8_t system_type = MAV_TYPE_GCS;
  uint8_t autopilot_type = MAV_AUTOPILOT_INVALID;
  
  uint8_t system_mode = 0; 
  uint32_t custom_mode = 0;                
  uint8_t system_state = 0;
  
  // Initialize the required buffers
  mavlink_message_t msg;
  uint8_t buf[MAVLINK_MAX_PACKET_LEN];
  
  // Pack the message
  mavlink_msg_heartbeat_pack(sysid,compid, &msg, system_type, autopilot_type, system_mode, custom_mode, system_state);
  
  // Copy the message to the send buffer
  uint16_t len = mavlink_msg_to_send_buffer(buf, &msg);
  
  // Send the message 
  delay(1000);
  Serial.write(buf, len);
}

/************************************************************
* @brief Sends a waypoint command
* @param NONE
* @return void
*************************************************************/

void command_waypoint() {

  //TARGET DRONE
  uint8_t _target_system = 1; // Target drone id
  uint8_t _target_component = 0; // Target component, 0 = all

  uint16_t seq = 0; // Sequence is always set to 0
  uint8_t frame = MAV_FRAME_GLOBAL; // Set target frame to global default
  uint16_t command = MAV_CMD_NAV_WAYPOINT; // Specific command for PX4 
  uint8_t current = 2; // Guided mode waypoint
  uint8_t autocontinue = 0; // Always 0
  float param1 = 0; // Loiter time
  float param2 = 1; // Acceptable range from target - radius in meters
  float param3 = 0; // Pass through waypoint
  float param4 = 0; // Desired yaw angle
  float x = 52.464217; // Latitude - degrees
  float y = -1.280222; // Longitude - degrees
  float z = 200; // Altitude - meters

  // Initialize the required buffers
  mavlink_message_t msg;
  uint8_t buf[MAVLINK_MAX_PACKET_LEN];

  // Pack the message
  mavlink_msg_mission_item_pack(1,1, &msg, _target_system, _target_component, seq, frame, command, current, autocontinue, param1, param2, param3, param4, x, y, z);

  // Copy the message to the send buffer
  uint16_t len = mavlink_msg_to_send_buffer(buf, &msg);
  // Send the message (.write sends as bytes) 
  delay(1000);
  Serial.write(buf, len);
}

That line sets something equal to GLOBAL_POSITION_INT. But you never tell the code what GLOBAL_POSITION_INT equals.

Where is the constant GLOBAL_POSITION_INT defined?

uint16_t msg = GLOBAL_POSITION_INT; declares the variable msg equal to GLOBAL_POSITION_INT which must already exist.

@zanek012, do not cross-post. Threads merged.

Apologies for the cross post.

I am confused because from my knowledge of the code, is the variable "command" being filled with the data "GLOBAL_POSITION_INT" rather than the GLOBAL_POSITION_INT being the variable? The reason I say this is because further down in the piece of code there is

uint16_t command = MAV_CMD_NAV_WAYPOINT;

If I removed the 'custom' command that I added and leave the code as per the example that I started with, it compiles even though I cannot find anywhere in the code where "MAV_CMD_NAV_WAYPOINT" is treated as a variable and defined

It may be defined in the header as part of the library.

If you set msg equal to GLOBAL_POSITION_INT, then what value should msg have? What is the value of GLOBAL_POSITION_INT? Is that something you made up or something you got from another example code?

Those constants (an all capitol letter name is assumed to be a constant) may be defined in the included library. Look at mavlink.h with a text editor to see.

In the line that I showed, the variable uint16_t msg is assigned the value of the constant GLOBAL_POSITION_INT. GLOBAL_POSITION_INT must be declared or #defined and assigned a value before it can be used

Thank you for the suggestion, I didn't think of checking the library. I have the mavlink documentation that shows the values that should be assigned to the all caps commands so I can edit it to include the commands I am trying to use

zanek012:
I installed the mavlink library

Please post a link to where you downloaded the mavlink library from.

zanek012:
I get "'GLOBAL_POSITION_INT' was not declared in this scope"

We need the FULL error output, not a screenshot. When you encounter an error you'll see a button on the right side of the orange bar "Copy error messages". Click that button and then paste the error in a message here using code tags.

I am using this mavlink library: GitHub - per1234/arduino-mavlink at ide-compatibility-updates

Here is the full error message:

Arduino: 1.8.1 (Windows 7), Board: "Arduino/Genuino Uno"

C:\Users\zkincaid\Work Folders\Documents\Arduino\mavlink_gps_test\mavlink_gps_test.ino: In function 'void command_location(int32_t, int32_t, int32_t)':

mavlink_gps_test:30: error: 'GLOBAL_POSITION_INT' was not declared in this scope

   uint16_t command = GLOBAL_POSITION_INT; // Specific command for Duo

                      ^

exit status 1
'GLOBAL_POSITION_INT' was not declared in this scope

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

I am going to give the code a try using the command number (33) rather than using GLOBAL_POSITION_INT because after looking at the mavlink library, the specific commands seem to be defined as their mavlink command number

Oh, hey that's my GitHub repository. I forked the original version of arduino-mavlink because it needed some changes to work with recent versions of the Arduino IDE. I'm glad if you can find it useful but I should warn you this is a fork of a project that hasn't been updated for four years so the version of the mavlink library included with it is probably far behind the latest mavlink library code. That might be a good idea for use with the included ArduinoMAVLink sketch since it was written for the included version of the library but since you're not using that sketch it might be better for you to use a current version of the mavlink library. You can get the latest version of the mavlink library generated for C/C++from:
v1 protocol: GitHub - mavlink/c_library_v1: MAVLink protocol C/C++ implementation auto-generated from latest protocol specs.
v2 protocol: GitHub - mavlink/c_library_v2: Official reference C / C++ library for the v2 protocol

Looking through all 3 of the libraries I don't find any definition of GLOBAL_POSITION_INT but I do see there is MAVLINK_MSG_ID_GLOBAL_POSITION_INT defined as 33 in all 3 of them so that might be the right one. I actually don't know anything about the mavlink protocol.