Skip to main content

ROS Coordinate Systems

Refer to ROS standard https://www.ros.org/reps/rep-0103.html:

  • For positions represented with reference to a initial body frame, FLU (NWU) should be used
  • However, if the position represents a geographic location (either global or local), ENU should be used
    • This includes /mavros/local_position, outputing ENU frame Code

Similarly, in RVIS visualisations, RGB represents the 3-axis of the coordinates in sequence. The default global coordinates is map. This map should represent ENU aligned global position or ENU aligned local position.

warning

Reading from this issue, we should note that NWU is neither a ROS standard nor a Mavros convention, when describing a location.

However, NWU is used in sensors for example IMU for their linear acceleration and angular rates, which creates confusion, by Mavros. (Mavlink always uses NED)

Frame ID and Coordinate Frames#

Naming convention: REP 105

Rule of thumb: sensor data should be in NED frame (depth, VIO), global position and orientation should be in ENU frame (Motion Capture, Code).

From Mavros to ROS (Planning)#

Frame IDCoordinate FrameRemarkExample
mapENUTrue North Aligned/mavros/local_position/pose (configurable in launch file)
map_nedNEDBy Mavros
base_linklocal ENUINCONSISTENT/mavros/local_position/odom, and static tf sent by mavros
base_link_frdlocal NEDBy MavrosShould use this as the pointcloud measurement frame
base_link_enushall we define this?

More Info

It appears that although ROS recommand NWU as the convention for local frame, but base_link in mavros uses ENU.

From Mavros to ROS (VIO)#

Frame IDCoordinate FrameRemarkExample
base_linkENU/mavros/imu/data/orientation
base_linklocal NWU/mavros/imu/data/angular_velocity, /mavros/imu/data/linear_acceleration
base_linklocal NWUINCONSISTENT/mavros/imu/data_raw/*

From ROS to Mavros (VIO)#

Frame IDCoordinate FrameRemarkExample
odomENUTrue North Aligned
odome_nedNEDBy Mavros/mavros/odometry/out with frame_id = "odom_ned"
    // Publish helper TFs used for frame transformation in the odometry plugin    std::vector<geometry_msgs::TransformStamped> transform_vector;    add_static_transform("map", "map_ned", Eigen::Affine3d(ftf::quaternion_from_rpy(M_PI, 0, M_PI_2)),transform_vector);    add_static_transform("odom", "odom_ned", Eigen::Affine3d(ftf::quaternion_from_rpy(M_PI, 0, M_PI_2)),transform_vector);    add_static_transform("base_link", "base_link_frd", Eigen::Affine3d(ftf::quaternion_from_rpy(M_PI, 0, 0)),transform_vector);
    tf2_static_broadcaster.sendTransform(transform_vector);

Case Study /mavros/local_position#

All message below assumes map as the frame id, and the child frame id is base_link. This means that map is representing ENU coordinates.

Also, the orientation is also converted to ENU frame, which means base_link is also in ENU frame.

tf#

The tf transformation is optionally sent by setting the parameter local_position/tf/send to true, located at px4_config.yaml

Last updated on