Skip to content

Commit 20e0dc1

Browse files
committed
Merge branch 'master' into waypoint-handler-devel
2 parents 1492744 + f8bdc25 commit 20e0dc1

File tree

7 files changed

+173
-43
lines changed

7 files changed

+173
-43
lines changed

freyja_controller.launch

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@
99

1010
<!-- allowed autopilots: "asctec" or "arducopter" -->
1111
<arg name="autopilot" default="arducopter" />
12-
<arg name="vicon_topic" default="/vicon/F1/F1" />
12+
<arg name="vicon_topic" />
1313

1414
<!-- use "device:baudrate" for apm, "device" for asctec -->
1515
<arg name="comm_port" default="/dev/ttyUSB0:57600"/>
1616
<arg name="total_mass" default="0.95"/>
17-
<arg name="thrust_scaler" default="200.0"/>
17+
<arg name="thrust_scaler" default="200.0"/>
1818

1919
<!-- launch a handler for discrete waypoints -->
2020
<arg name="use_waypoint_handler" default="false" />
@@ -27,28 +27,33 @@
2727
<arg name="use_examples" default="false"/>
2828
<arg name="example_number" default="0" />
2929

30+
3031
<!-- state source can be: "apm", "asctec", "vicon" or "onboard_camera" -->
3132
<!-- implemented filters: "median", "gauss" and "lwma" -->
3233
<node name="state_manager" pkg="state_manager" type="state_manager_node">
33-
<param name="state_source" type="string" value="vicon" />
34-
<param name="filter_type" type="string" value="median" />
35-
<param name="vicon_topic" type="string" value="$(arg vicon_topic)" />
34+
<param name="state_source" type="string" value="vicon" />
35+
<param name="filter_type" type="string" value="median" />
36+
<param name="vicon_topic" type="string" value="$(arg vicon_topic)" />
3637
</node>
3738

39+
40+
3841
<!-- control node (see velctrl flag above) -->
3942
<node name="lqg_controller" pkg="lqg_control" type="lqg_control_node"
40-
output="screen" if="$(eval not use_velctrl_only)">
41-
<param name="controller_rate" value="45" type="int" />
42-
<param name="total_mass" type="double" value="$(arg total_mass)"/>
43-
<param name="use_stricter_gains" type="bool" value="false" />
44-
<param name="estimator_rate" type="int" value="70" />
45-
<param name="bias_compensation" type="bool" value="$(arg bias_compensation)" />
43+
output="screen" if="$(eval not use_velctrl_only)">
44+
<param name="controller_rate" type="int" value="45" />
45+
<param name="total_mass" type="double" value="$(arg total_mass)"/>
46+
<param name="use_stricter_gains" type="bool" value="false" />
47+
<param name="estimator_rate" type="int" value="50" />
48+
<param name="bias_compensation" type="string" value="$(arg bias_compensation)" />
49+
<param name="mass_estimation" type="bool" value="true" />
50+
<param name="mass_correction" type="bool" value="false" />
4651
</node>
4752

4853
<node name="lqr_vel_controller" pkg="lqr_control" type="lqr_vel_ctrl_node"
49-
if="$(eval use_velctrl_only)">
50-
<param name="controller_rate" type="int" value="30" />
51-
<param name="total_mass" value="$(arg total_mass)" type="double" />
54+
if="$(eval use_velctrl_only)">
55+
<param name="controller_rate" type="int" value="30" />
56+
<param name="total_mass" type="double" value="$(arg total_mass)" />
5257
</node>
5358

5459
<!-- autopilot communication node -->
@@ -59,7 +64,10 @@
5964

6065
<!-- apm/px4 needs a handler for translation, plus a mavros node -->
6166
<group if="$(eval autopilot=='arducopter')">
62-
<node name="apm_handler" pkg="apm_handler" type="apm_handler_node" />
67+
<node name="apm_handler" pkg="apm_handler" type="apm_handler_node">
68+
<param name="thrust_scaler" type="double" value="$(arg thrust_scaler)" />
69+
</node>
70+
6371
<include file="$(find freyja_configfiles)/apm_nimbus.launch">
6472
<arg name="fcu_url" value="$(arg comm_port)"/>
6573
</include>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Custom status msg that keeps track of system status
2+
## Autopilot handlers must fill these using their own
3+
## communication interfaces. Not all information may
4+
## be available to a handler. Fill -1 if so.
5+
6+
# No internal component of Freyja should depend on
7+
# this msg, i.e., no state machine transitions are
8+
# effected through this. The primary purpose of this
9+
# msg is to ease log analysis. External tools/code
10+
# are, of course, free to consume it however.
11+
12+
Header header
13+
int8 is_connected # comms to vehicle
14+
int8 is_armed # motors on
15+
int8 is_compctrl # mode == computer

state_manager/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ find_package(catkin REQUIRED COMPONENTS
1919
freyja_msgs
2020
sensor_msgs
2121
nav_msgs
22+
std_srvs
2223
)
2324

2425

state_manager/include/state_manager.h

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,12 @@
1212
#include <ros/ros.h>
1313
#include <geometry_msgs/TransformStamped.h>
1414
#include <geometry_msgs/TwistStamped.h>
15+
#include <geometry_msgs/Vector3.h>
1516
#include <sensor_msgs/NavSatFix.h>
1617
#include <nav_msgs/Odometry.h>
18+
#include <std_msgs/Float64.h>
1719
#include <tf/tf.h>
20+
#include <std_srvs/SetBool.h>
1821

1922
#include <freyja_msgs/CurrentState.h>
2023
#include <freyja_msgs/AsctecData.h>
@@ -24,6 +27,8 @@
2427
typedef geometry_msgs::TransformStamped TFStamped;
2528
typedef geometry_msgs::TwistStamped TwStamped;
2629
typedef nav_msgs::Odometry CameraOdom;
30+
typedef std_srvs::SetBool::Request BoolServReq;
31+
typedef std_srvs::SetBool::Response BoolServRsp;
2732

2833
#define DEG2RAD(D) ((D)*3.1415326/180.0)
2934
#define F_PI 3.14153
@@ -69,13 +74,21 @@ class StateManager
6974
FreyjaFilters pose_filter_;
7075
FreyjaFilters rate_filter_;
7176

77+
/* containers for handling gps data */
7278
double home_lat_, home_lon_;
7379
bool have_location_fix_;
80+
double compass_yaw_;
81+
82+
bool have_arming_origin_;
83+
double map_rtk_pn_, map_rtk_pe_, map_rtk_pd_;
84+
double arming_gps_pn_, arming_gps_pe_, arming_gps_pd_;
85+
double gps_odom_pn_, gps_odom_pe_, gps_odom_pd_;
86+
double rtk_baseoffset_pn_, rtk_baseoffset_pe_, rtk_baseoffset_pd_;
7487

7588
public:
7689
StateManager();
7790
/* launch-time parameter specifies which one to pick */
78-
void initApmManager();
91+
void initPixhawkManager();
7992
void initAsctecManager();
8093
void initViconManager();
8194
void initCameraManager();
@@ -87,17 +100,40 @@ class StateManager
87100
/* Callback handler for asctec_onboard_data */
88101
ros::Subscriber asctec_data_sub_;
89102
void asctecDataCallback( const freyja_msgs::AsctecData::ConstPtr & );
90-
91-
/* Callback handlers for mavros data */
92-
ros::Subscriber mavros_gps_sub_;
93-
ros::Subscriber mavros_vel_sub_;
94-
void mavrosGpsCallback( const sensor_msgs::NavSatFix::ConstPtr & );
95-
void mavrosGpsVelCallback( const TwStamped::ConstPtr & );
96103

97104
/* Callback handler for camera updates */
98105
ros::Subscriber camera_estimate_sub_;
99106
void cameraUpdatesCallback( const CameraOdom::ConstPtr & );
100107

108+
/* Callback handlers for mavros data */
109+
ros::Subscriber mavros_gpsraw_sub_;
110+
ros::Subscriber mavros_vel_sub_;
111+
ros::Subscriber compass_sub_;
112+
ros::Subscriber mavros_gpsodom_sub_;
113+
ros::Subscriber mavros_rtk_sub_;
114+
void mavrosGpsOdomCallback( const nav_msgs::Odometry::ConstPtr & );
115+
void mavrosCompassCallback( const std_msgs::Float64::ConstPtr & );
116+
void mavrosRtkBaselineCallback( const geometry_msgs::Vector3::ConstPtr & );
117+
118+
void mavrosGpsRawCallback( const sensor_msgs::NavSatFix::ConstPtr & );
119+
120+
/* handlers for locking map frame origins */
121+
inline void lockArmingGps( bool _lock = true )
122+
{
123+
arming_gps_pn_ = _lock? gps_odom_pn_ : 0.0;
124+
arming_gps_pe_ = _lock? gps_odom_pe_ : 0.0;
125+
arming_gps_pd_ = _lock? gps_odom_pd_ : 0.0;
126+
}
127+
inline void lockMapRTK( bool _lock = true )
128+
{
129+
map_rtk_pn_ = _lock? rtk_baseoffset_pn_ : 0.0;
130+
map_rtk_pe_ = _lock? rtk_baseoffset_pe_ : 0.0;
131+
map_rtk_pd_ = _lock? rtk_baseoffset_pd_ : 0.0;
132+
}
133+
134+
ros::ServiceServer maplock_srv_;
135+
bool maplockArmingHandler( BoolServReq&, BoolServRsp& );
136+
101137

102138
/* Publisher for state information */
103139
ros::Publisher state_pub_;

state_manager/package.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
<build_depend>freyja_msgs</build_depend>
1616
<build_depend>sensor_msgs</build_depend>
1717
<build_depend>nav_msgs</build_depend>
18+
<build_depend>std_srvs</build_depend>
1819

1920
<run_depend>roscpp</run_depend>
2021
<run_depend>std_msgs</run_depend>
@@ -23,5 +24,6 @@
2324
<run_depend>geometry_msgs</run_depend>
2425
<run_depend>sensor_msgs</run_depend>
2526
<run_depend>nav_msgs</run_depend>
27+
<run_depend>std_srvs</run_depend>
2628

2729
</package>

state_manager/src/callback_implementations.cpp

Lines changed: 74 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ void StateManager::viconCallback( const TFStamped::ConstPtr &msg )
7474
last_yaw_ = yaw;
7575

7676
/* Copy over and publish right away */
77-
freyja_msgs::CurrentState state_msg;
77+
static freyja_msgs::CurrentState state_msg;
7878
state_msg.header.stamp = ros::Time::now();
7979
for( uint8_t idx = 0; idx < STATE_VECTOR_LEN; idx++ )
8080
state_msg.state_vector[idx] = state_vector_[idx];
@@ -152,11 +152,12 @@ void StateManager::asctecDataCallback( const freyja_msgs::AsctecData::ConstPtr &
152152
state_pub_.publish( state_msg );
153153
}
154154

155-
void StateManager::mavrosGpsCallback( const sensor_msgs::NavSatFix::ConstPtr& msg )
155+
void StateManager::mavrosGpsRawCallback( const sensor_msgs::NavSatFix::ConstPtr& msg )
156156
{
157+
/*
157158
if( msg -> status.status >= 0 && !have_location_fix_ )
158159
{
159-
/* first location fix */
160+
// first location fix
160161
home_lat_ = msg -> latitude;
161162
home_lon_ = msg -> longitude;
162163
have_location_fix_ = true;
@@ -167,30 +168,88 @@ void StateManager::mavrosGpsCallback( const sensor_msgs::NavSatFix::ConstPtr& ms
167168
168169
state_vector_[0] = ( (msg->latitude)/10000000.0 - home_lat_ )*111050.51;
169170
state_vector_[1] = ( (msg->longitude)/10000000.0 - home_lon_ )*84356.28;
171+
*/
172+
}
173+
170174

175+
176+
void StateManager::mavrosCompassCallback( const std_msgs::Float64::ConstPtr &msg )
177+
{
178+
compass_yaw_ = msg -> data;
171179
}
172180

173-
void StateManager::mavrosGpsVelCallback( const TwStamped::ConstPtr &msg )
181+
void StateManager::mavrosGpsOdomCallback( const nav_msgs::Odometry::ConstPtr &msg )
174182
{
175-
if( !have_location_fix_ )
183+
/* Callback for odometry direct from the Pixhawk.
184+
Note that this is Pixhawk's best estimate of where it is in the world,
185+
there is no need to filter it, only structure it to our format.
186+
Likely topics:
187+
/mavros/global_position/local --> does not zero at arming.
188+
/mavros/local_position/local --> zeros at arming, has IMU frame quirk.
189+
*/
190+
191+
static double pn, pe, pd, vn, ve, vd;
192+
193+
// update containers anyway (needed for capturing arming location)
194+
gps_odom_pn_ = msg -> pose.pose.position.y;
195+
gps_odom_pe_ = msg -> pose.pose.position.x;
196+
gps_odom_pd_ = -( msg -> pose.pose.position.z );
197+
198+
if( !have_arming_origin_ )
199+
{
200+
ROS_INFO_THROTTLE( 5, "StateManager:: Waiting for arming .." );
176201
return;
202+
}
177203

178-
double time_since = (ros::Time::now() - lastUpdateTime_).toSec();
204+
// armed at this point
205+
pn = gps_odom_pn_ + map_rtk_pn_ - arming_gps_pn_;
206+
pe = gps_odom_pe_ + map_rtk_pe_ - arming_gps_pe_;
207+
pd = gps_odom_pd_ + map_rtk_pd_ - arming_gps_pd_;
179208

180-
state_vector_[3] = msg -> twist.linear.x;
181-
state_vector_[4] = msg -> twist.linear.y;
182-
state_vector_[5] = msg -> twist.linear.z;
209+
vn = msg -> twist.twist.linear.y;
210+
ve = msg -> twist.twist.linear.x;
211+
vd = -( msg -> twist.twist.linear.z );
183212

184-
state_vector_[12] = time_since;
213+
static freyja_msgs::CurrentState state_msg;
214+
state_msg.state_vector[0] = pn;
215+
state_msg.state_vector[1] = pe;
216+
state_msg.state_vector[2] = pd;
217+
state_msg.state_vector[3] = vn;
218+
state_msg.state_vector[4] = ve;
219+
state_msg.state_vector[5] = vd;
220+
state_msg.state_vector[8] = DEG2RAD( compass_yaw_ );
185221

186-
lastUpdateTime_ = ros::Time::now();
187-
188-
freyja_msgs::CurrentState state_msg;
189222
state_msg.header.stamp = ros::Time::now();
190-
for( uint8_t idx = 0; idx < STATE_VECTOR_LEN; idx++ )
191-
state_msg.state_vector[idx] = state_vector_[idx];
192223
state_pub_.publish( state_msg );
224+
}
225+
226+
227+
void StateManager::mavrosRtkBaselineCallback( const geometry_msgs::Vector3::ConstPtr &msg )
228+
{
229+
rtk_baseoffset_pn_ = msg -> x;
230+
rtk_baseoffset_pe_ = msg -> y;
231+
rtk_baseoffset_pd_ = msg -> z;
232+
}
193233

234+
bool StateManager::maplockArmingHandler( BoolServReq& rq, BoolServRsp& rp )
235+
{
236+
/* Service handler for when the vehicle is armed or disarmed.
237+
This must lock in/release all the map offsets needed by manager.
238+
*/
239+
if( !have_arming_origin_ )
240+
{
241+
lockArmingGps(); // set this locatin as origin
242+
lockMapRTK(); // capture current offset from rtk base (zero if no rtk)
243+
have_arming_origin_ = true;
244+
ROS_WARN( "StateManager::Origin set, locking RTK map-frame!" );
245+
}
246+
else
247+
{
248+
lockArmingGps( false );
249+
lockMapRTK( false );
250+
have_arming_origin_ = false;
251+
ROS_WARN( "StateManager::Origin cleared, unlocking RTK map-frame!" );
252+
}
194253
}
195254

196255
void StateManager::cameraUpdatesCallback( const CameraOdom::ConstPtr &msg )

state_manager/src/state_manager.cpp

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ StateManager::StateManager() : nh_(), priv_nh_("~")
2323
else if( state_source_ == "asctec" )
2424
initAsctecManager();
2525
else if (state_source_ == "apm" )
26-
initApmManager();
26+
initPixhawkManager();
2727
else if( state_source_ == "onboard_camera" )
2828
initCameraManager();
2929

@@ -98,12 +98,21 @@ void StateManager::initAsctecManager()
9898
&StateManager::asctecDataCallback, this );
9999
}
100100

101-
void StateManager::initApmManager()
101+
void StateManager::initPixhawkManager()
102102
{
103-
mavros_gps_sub_ = nh_.subscribe( "/mavros/global_position/global", 1,
104-
&StateManager::mavrosGpsCallback, this );
105-
mavros_vel_sub_ = nh_.subscribe( "/mavros/global_position/gp_vel", 1,
106-
&StateManager::mavrosGpsVelCallback, this );
103+
have_arming_origin_ = false;
104+
mavros_gpsraw_sub_ = nh_.subscribe( "/mavros/global_position/global", 1,
105+
&StateManager::mavrosGpsRawCallback, this );
106+
mavros_gpsodom_sub_ = nh_.subscribe( "/mavros/global_position/local", 1,
107+
&StateManager::mavrosGpsOdomCallback, this,
108+
ros::TransportHints().tcpNoDelay() );
109+
mavros_rtk_sub_ = nh_.subscribe( "/ublox_f9p_rtkbaseline", 1,
110+
&StateManager::mavrosRtkBaselineCallback, this );
111+
compass_sub_ = nh_.subscribe( "/mavros/global_position/compass_hdg", 1,
112+
&StateManager::mavrosCompassCallback, this );
113+
114+
maplock_srv_ = nh_.advertiseService( "/lock_arming_mapframe",
115+
&StateManager::maplockArmingHandler, this );
107116
}
108117

109118
void StateManager::initCameraManager()

0 commit comments

Comments
 (0)