-
Notifications
You must be signed in to change notification settings - Fork 20
Coordinate Systems
GAMS' coordinate system capabilities are designed to provide easy conversion between different kinds of coordinate reference frames, embedded within each other. For example, you might represent the Earth using a GPS_Frame reference frame, and embed a Cartesian_Frame within it, with an origin at a given longitude and latitude. This would allow for manipulating locations on a scale of meters near that origin, automatically translating back to latitude and longitudes as needed.
The basic coordinate types, Location, Rotation, and Pose (which combines Location and Rotation information into one object) bind to a reference frame. GAMS provides a default Cartesian reference frame, suitable if your application does not require any conversion between reference frames.
GAMS supports two kinds of reference frames: Cartesian_Frame, and GPS_Frame. The GPS_Frame is a simple spherical model. You may construct a GPS_Frame using an optional radius parameter to create frames representing bodies other than Earth. GPS_Frame provides constants for Earth, Mars, and the Moon.
A reference frame may be constructed simply as follows:
GPS_Frame gps_frame;
or
Cartesian_Frame cart_frame;
The above frames would be parentless. A frame may have a parent, by specifying an origin point within another frame. By creating frame objects with parents, coordinates can easily convert between any frames in the resulting tree. For example:
GPS_Frame earth_frame; // Latitude/Longitude frame representing planet Earth
// Cartesian frame representing a house, at the given Longitude and Latitude
Cartesian_Frame house_frame(Location(earth_frame,-79.9500588, 40.4464481));
// Cartesian frame representing a given room in the house
Cartesian_Frame room_frame(Location(House_Frame, 10, 20));
In this example, coordinates within room_frame may be converted to coordinates with earth_frame. Instead of using Location, Pose may be used instead to specify frames that are rotated with respect to another.
GAMS currently does not yet support fully converting from GPS_Frames to Cartesian_Frames; specifically, coordinates within a GPS_Frame cannot convert to a Cartesian_Frame that is rotated with respect to it.
GAMS supports three coordinate types: Location, Rotation, and Pose. All coordinates bind to a frame (the first argument of any constructor). If you construct a coordinate of any type omitting the frame argument, it will bind to the default reference frame, a Cartesian frame that has no parent.
Location represents position information. It can represent coordinates within any type of 3-dimensional coordinate system (there aren't separate classes for GPS vs Cartesian coordinates). Location provides methods for accessing those coordinates according to various naming conventions:
Location earth_loc(earth_frame, -79.9494575, 40.4465197);
earth_loc.lat(); // Latitude (40.4465197)
earth_loc.lng(); // Longitude (-79.9494575)
earth_loc.alt(); // altitude (0 meters above surface, the default)
Location room_loc(room_frame, 1, 2);
room_loc.x(); // x-coordinate (1 meter from origin)
room_loc.y(); // y-coordinate (2 meters from origin)
room_loc.z(); // z-coordinate (0 meters above origin, the default)
These different functions are for the sake of readable code; there is no underlying difference between, for example, earth_loc.lng() and earth_loc.x().
To set coordinates, simply pass the new value as an argument to the function for that coordinate; e.g., room_loc.z(2).
The Rotation class represents a rotation or orientation relative to its frame. There are two primary ways to construct a Rotation. The easiest is to specify one of the fundamental axes, and a rotation (in degrees, counter clockwise if looking from above) around that axis:
Rotation simple_rot(room_frame, Rotation::Z_axis, 90);
The more expressive form represents the rotation in an angle-axis vector format. For this, the rx, ry, and rz parameters represent a 3-vector which points in the direction of the axis of rotation, and whose magnitude is the amount of rotation about that axis in radians. The above rotation could be specified instead as follows:
Rotation simple_rot(room_frame, 0, 0, M_PI / 2);
This notation can represent any possible orientation relative to the frame, while the first notation is limited to simple rotations.
The Pose class combines both Location and Rotation information. It may be constructed as follows:
Pose room_pose(room_frame, 3, 1, 0, 0, 0, M_PI / 2);
Where the location 3-vector is specified first, followed by the rotation 3-vector. A variety of other constructors are avialable (see the Doxygen documentation).
GAMS provides the following methods on all coordinates (Location, Rotations, and Poses):
transform_to creates a copy of a coordinate, but in a new reference frame. This new frame must somehow be related to the coordinate's current frame.
Pose gps_pose = room_pose.transform_to(earth_frame);
transform_this_to transforms the coordinate object, in place, to the new reference frame. Again, it must be related to the current frame.
room_pose.transform_to(earth_frame);
distance_to finds the distance between the two coordinates. For Location and Pose, this is the number of meters between them. For Rotation, this is the number of degrees between them. Note that the coordinates need not be in the same reference frame, but they must be transformable to a common reference frame. Rotation and Pose also provide angle_to. For Rotation, this is synonymous with distance_to. For Poses, this finds the degrees between the Rotation parts of the Poses.
room_loc.distance_to(earth_loc); // returns sqrt(5)