mavlink / mavros

MAVLink to ROS gateway with proxy for Ground Control Station
Other
902 stars 993 forks source link

mavros client server wrapped in a class #488

Closed tuofeichen closed 8 years ago

tuofeichen commented 8 years ago

Hey guys, Wrote a small offboard control code using mavros and I call the mavros/cmd/state and mavros/cmd/arming using mavros_msgs::SetMode and mavros_msgs::CommandBool to arm and set offboard mode. Everything works fine when I just put everything into one cpp file.

However when I tried to wrap it up into a class and include it in a main.cpp: (the code below is the class definition)

#include "px4_offboard/include.h"

class CtrlPx4
{
public:
  CtrlPx4();

private:
  // subscriber callbacks
  void stateCallback(const mavros_msgs::State);
  void joyVelCallback(const geometry_msgs::Twist);
  void joyStateCallback(const std_msgs::Byte);

  // node initialization
  ros::NodeHandle nh;
  ros::Publisher mavros_control_pub; // here the number is the buffer
  ros::ServiceClient mavros_set_mode_client;
  ros::ServiceClient mavros_armed_client;
  ros::Subscriber state_sub;
  ros::Subscriber joy_vel_sub;
  ros::Subscriber joy_state_sub;

  // flight state
  myState state_set{0,0,VELOCITY}, state_read{0,0,VELOCITY};

  //publishing msgs
  mavros_msgs::SetMode set_mode;
  mavros_msgs::CommandBool set_armed;
  geometry_msgs::TwistStamped fmu_controller_setpoint;

};

CtrlPx4::CtrlPx4()
{
  mavros_control_pub     =   nh.advertise<geometry_msgs::TwistStamped>("/mavros/setpoint_velocity/cmd_vel",1000);
  mavros_set_mode_client =   nh.serviceClient<mavros_msgs::State>("/mavros/cmd/state");
  mavros_armed_client    =   nh.serviceClient<mavros_msgs::CommandBool>("/mavros/cmd/arming");
  state_sub              =   nh.subscribe("/mavros/state", 1000, &CtrlPx4::stateCallback,this);
  joy_vel_sub            =   nh.subscribe("/joy/cmd_vel",1000,&CtrlPx4::joyVelCallback,this);
  joy_state_sub          =   nh.subscribe("/joy/state",1000,&CtrlPx4::joyStateCallback,this);
};

This is what I put in include.h

#include "ros/ros.h"
#include <iostream>
#include <string.h>
#include <mavros/mavros.h>
#include <mavros_msgs/State.h>
#include <mavros_msgs/CommandBool.h>
#include <mavros_msgs/CommandTOL.h>
#include <mavros_msgs/SetMode.h>
#include <mavros_msgs/OverrideRCIn.h>
#include "std_msgs/String.h"
#include "std_msgs/Byte.h"
#include "geometry_msgs/TwistStamped.h"
#include <sstream>

I got a compiling error:

# warning "No MAVLINK_DIALECT specified. fallback to " MAVLINK_DIALECT
   ^
In file included from /opt/ros/indigo/include/ros/service_client.h:33:0,
                 from /opt/ros/indigo/include/ros/node_handle.h:35,
                 from /opt/ros/indigo/include/ros/ros.h:45,
                 from /home/parallels/catkin_ws/src/px4_offboard/include/px4_offboard/include.h:4,
                 from /home/parallels/catkin_ws/src/px4_offboard/src/basic.cpp:1:
/opt/ros/indigo/include/ros/service_traits.h: In instantiation of ‘static const char* ros::service_traits::MD5Sum<M>::value() [with M = mavros_msgs::State_<std::allocator<void> >]’:
/opt/ros/indigo/include/ros/service_traits.h:79:103:   required from ‘const char* ros::service_traits::md5sum() [with M = mavros_msgs::State_<std::allocator<void> >]’
/opt/ros/indigo/include/ros/service_client_options.h:95:34:   required from ‘void ros::ServiceClientOptions::init(const string&, bool, const M_string&) [with Service = mavros_msgs::State_<std::allocator<void> >; std::string = std::basic_string<char>; ros::M_string = std::map<std::basic_string<char>, std::basic_string<char> >]’
/opt/ros/indigo/include/ros/node_handle.h:1251:5:   required from ‘ros::ServiceClient ros::NodeHandle::serviceClient(const string&, bool, const M_string&) [with Service = mavros_msgs::State_<std::allocator<void> >; std::string = std::basic_string<char>; ros::M_string = std::map<std::basic_string<char>, std::basic_string<char> >]’
/home/parallels/catkin_ws/src/px4_offboard/src/CtrlPx4.cpp:38:86:   required from here
/opt/ros/indigo/include/ros/service_traits.h:47:35: error: ‘__s_getServerMD5Sum’ is not a member of ‘mavros_msgs::State_<std::allocator<void> >’
     return M::__s_getServerMD5Sum().c_str();
                                   ^
make[2]: *** [px4_offboard/CMakeFiles/basic.dir/src/basic.cpp.o] Error 1
make[1]: *** [px4_offboard/CMakeFiles/basic.dir/all] Error 2
make: *** [all] Error 2
Invoking "make -j2 -l2" failed

Googling doesn't seem to help. Anyone can help me out?

vooon commented 8 years ago
#include <mavros/mavros.h>

Is needed only for writing plugin. Because you use ROS API you only need message/service headers and roscpp.

Second error somewhat repaled to rosgen. Try to clean by catkin clean --all and try again.

tuofeichen commented 8 years ago

Hi @vooon Thanks for the response. I tried commenting out mav/mavros.h and catkin clean --all. Unfortunately the error persists, any other suggestions?

I guess also to clarify and reiterate, when I comment out the two lines of serviceClient assignment in the constructor, everything compiles again. Any idea why?

Thank you

Best Francis

vooon commented 8 years ago

Try to comment out mavros_msgs::State subscription line. 02 февр. 2016 г. 18:55 пользователь "tuofeichen" notifications@github.com написал:

Hi @vooon https://github.com/vooon Thanks for the response. I tried commenting out mav/mavros.h and catkin clean --all. Unfortunately the error persists, any other suggestions?

Thank you

Best Francis

— Reply to this email directly or view it on GitHub https://github.com/mavlink/mavros/issues/488#issuecomment-178651681.

tuofeichen commented 8 years ago

Hi @vooon With the serviceClient there, and comment out the subscription code, still got the same error.

vooon commented 8 years ago

Ohh, i missed that: mavros_msgs::State is message not service. So you write incorrect code:

// there no "~cmd/state" service
nh.serviceClient<mavros_msgs::State>("/mavros/cmd/state");

I suppose you wanted to subscribe on "~state" and use "~set_mode" (mavros_msgs::SetMode) to change mode.

tuofeichen commented 8 years ago

Oh you're right... Ah. copy and paste error. Thank you so much!

On Tuesday, 2 February 2016, Vladimir Ermakov notifications@github.com wrote:

Ohh, i missed that: mavros_msgs::State is message not service. So you write incorrect code:

// there no "~cmd/state" service nh.serviceClient("/mavros/cmd/state");

I suppose you wanted to subscribe on "~state" and use "~set_mode" ( mavros_msgs::SetMode) to change mode.

— Reply to this email directly or view it on GitHub https://github.com/mavlink/mavros/issues/488#issuecomment-178828618.