/* Adept MobileRobots Robotics Interface for Applications (ARIA) Copyright (C) 2004, 2005 ActivMedia Robotics LLC Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. Copyright (C) 2011, 2012, 2013 Adept Technology This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA If you wish to redistribute ARIA under different terms, contact Adept MobileRobots for information about a commercial version of ARIA at robots@mobilerobots.com or Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 */ /* \file ArMapObject.h * \brief Contains the definition of the ArMapObject class. * \date 06/27/08 * \author K. Cunningham */ #ifndef ARMAPOBJECT_H #define ARMAPOBJECT_H #include "ariaTypedefs.h" #include "ariaUtil.h" /// A point or region of interest in an Aria map. /** * ArMapObject contains the data related to an Aria map object, i.e a point or * region of interest in an Aria map that is not part of the sensed obstacle * data. Examples of map objects include goals, docks, forbidden lines, and * forbidden areas. Applications may define their own custom ArMapObject types * using the ArMap MapInfo mechanism. See @ref ArMap for more information. * * The basic attributes of an ArMapObject include the type of the map object, * an optional name of the object, and its position information. As mentioned * above, there are two basic categories of ArMapObjects: * * - Points: A single ArPose in the map. By convention, if a map object * can have an optional heading, then "WithHeading" appears at the end of * the object type when the heading is specified. For example, "Goal" * designates an (x,y) location in the map (any heading or theta value should * be ignored) and "GoalWithHeading" designates * an (x,y,th) location. * * - Regions: A set of two ArPoses ("from" and "to") which define a rectangle * or a line. Rectangles may have an associated rotation value. It is the * rotation to be applied to the "from" and "to" poses around * the global origin . To retrieve the list of line segments that * comprise the rotated rectangle's perimeter, use the getFromToSegments() * method. * * Note that the ArMapObject is generally immutable. If an object needs to be * changed, then the original version should simply be replaced with a new one. * See ArMap::getMapObjects(), ArMap::setMapObjects(), and ArMap::mapChanged(). * **/ class ArMapObject { public: /// Creates a new ArMapObject whose attributes are as specified in the given arguments /** * @param arg the ArArgumentBuilder * from which to create the ArMapObject; this * should correspond to a parsed line in the ArMap file * @return ArMapObject * the newly created map object, or NULL if an error * occurred **/ AREXPORT static ArMapObject *createMapObject(ArArgumentBuilder *arg); /// ArArgumentBuilder indices for the various map object attributes enum ArgIndex { TYPE_ARG_INDEX = 0, POSE_X_ARG_INDEX = 1, POSE_Y_ARG_INDEX = 2, TH_ARG_INDEX = 3, DESC_ARG_INDEX = 4, ICON_ARG_INDEX = 5, NAME_ARG_INDEX = 6, LAST_POSE_ARG_INDEX = NAME_ARG_INDEX, FROM_X_ARG_INDEX = 7, FROM_Y_ARG_INDEX = 8, TO_X_ARG_INDEX = 9, TO_Y_ARG_INDEX = 10, LAST_ARG_INDEX = TO_Y_ARG_INDEX }; enum { ARG_INDEX_COUNT = LAST_ARG_INDEX + 1 }; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Instance Methods // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /// Constructor /** * @param type the char * type of the map object (e.g. "Goal", "ForbiddenLine"); * must be non-empty * @param pose the primary ArPose of the map object; for points, this is its * location; for rectangles, this specifies the rotation of the rectangle (in * pose.getTh()) * @param description an optional char * description of the object. * @param iconName char * currently unused: use "ICON" or NULL as a dummy value. Must * be a non-empty, non-whitespace string. * @param name the char * name of the map object; depending on the object type, * this may be optional or required * @param hasFromTo a bool set to true if the object is a region (i.e. line or * rectangle); false if the object is a point * @param fromPose the ArPose that defines the start point of the region object; * applicable only when hasFromTo is true * @param toPose the ArPose that defines the end point of the region object; * applicable only when hasFromTo is true **/ AREXPORT ArMapObject(const char *type, ArPose pose, const char *description, const char *iconName, const char *name, bool hasFromTo, ArPose fromPose, ArPose toPose); /// Copy constructor AREXPORT ArMapObject(const ArMapObject &mapObject); /// Assignment operator AREXPORT ArMapObject &operator=(const ArMapObject &mapObject); /// Destructor AREXPORT virtual ~ArMapObject(); // -------------------------------------------------------------------------- // Text Attributes: // -------------------------------------------------------------------------- /// Returns the type of the map object AREXPORT const char *getType(void) const; /// Returns the "base" (or root) type of the map object /** * If the map object type ends with "WithHeading", then the base is the * corresponding heading-less type. For example, "GoalWithHeading" has a * base type of "Goal". * * If the map object type does not end with "WithHeading", then the base * is the same as the type. **/ AREXPORT const char *getBaseType(void) const; /// Returns the name of the map object (if any) AREXPORT const char *getName(void) const; /// Returns the optional description of the map object AREXPORT const char *getDescription() const ; /// Returns the icon string of the object /** * The use of the ICON field is application-dependent. It currently contains * either the string "ICON" or "ID=". The ID is used only when auto-numbering * has been turned on in the MapInfo. **/ AREXPORT const char *getIconName(void) const; /// Returns the numerical identifier of the object, when auto-numbering is on. /** * This method returns 0 when auto-numbering is off. **/ AREXPORT int getId() const; /// Sets the description of the map object /** * This method really should only be called immediately after the object * is created, and before it is added to the map. (Since the map object * isn't intended to be mutable.) It exists for backwards compatibility. **/ AREXPORT void setDescription(const char *description); // -------------------------------------------------------------------------- // Position Attributes: // -------------------------------------------------------------------------- /// Returns the primary pose of the object /** * For points, this is the map object's location; for rectangles, this * specifies the rotation of the rectangle (in getPose().getTh()) **/ AREXPORT ArPose getPose(void) const; /// Returns true if the map object has valid "from/to" poses (i.e. is a line or rectangle) AREXPORT bool hasFromTo(void) const; /// Returns the "from" pose for lines and rectangles; valid only if hasFromTo() AREXPORT ArPose getFromPose(void) const; /// Returns the "to" pose for lines and rectangles; valid only if hasFromTo() AREXPORT ArPose getToPose(void) const; /// Returns the optional rotation of a rectangle; or 0 if none /** * Note that this function doesn't know whether it actually makes sense * for this map object to have the rotation. (For example, it makes sense * on a ForbiddenArea but not a ForbiddenLine.) * **/ AREXPORT double getFromToRotation(void) const; /// Gets a list of fromTo line segments that have been rotated /** * Note that this function doesn't know whether it actually makes sense * for this map object to have the rotation. (For example, it makes sense * on a ForbiddenArea but not a ForbiddenLine.) This is just here so * that everyone doesn't have to do the same calculation. Note that * this might be a little more CPU/Memory intensive transfering * these around, so you may want to keep a copy of them if you're * using them a lot (but make sure you clear the copy if the map * changes). It may not make much difference on a modern processor * though (its set up this way for safety). **/ AREXPORT std::list getFromToSegments(void); /// Gets a line segment that goes from the from to the to /** * Note that this function doesn't know whether this is supposed to * be a rectangle or a line. (For example, it makes sense on a * ForbiddenLine but not a ForbiddenAra.) This is just here to * store it. Note that this might be a little more CPU/Memory * intensive transfering these around, so you may want to keep a * copy of them if you're using them a lot (but make sure you clear * the copy if the map changes). It may not make much difference on * a modern processor though (its set up this way for safety). **/ AREXPORT ArLineSegment getFromToSegment(void); /// Computes the center pose of the map object. /** * This method determines the center of map objects that have a "from" and a * "to" pose (i.e. lines and rectangles). For map objects that are poses, * this method simply returns the pose. **/ AREXPORT ArPose findCenter(void) const; // -------------------------------------------------------------------------- // I/O Methods // -------------------------------------------------------------------------- /// Returns the text representation of the map object /** * The returned string is suitable for writing to the ArMap file. Note that * the string does NOT include the map object's optional parameters. **/ AREXPORT const char *toString() const; /// Returns the text representation of the map object /** * This method is equivalent to toString(); **/ const char *getStringRepresentation() const { return toString(); } /// Writes the map object to the ArLog. /** * @param intro an optional string that should appear before the object **/ AREXPORT void log(const char *intro = NULL) const; // -------------------------------------------------------------------------- // Miscellaneous Methods // -------------------------------------------------------------------------- /// Less than operator (for sets), orders by position AREXPORT bool operator<(const ArMapObject& other) const; /// Gets the fileName of the object (probably never used for maps) /** * This method is maintained solely for backwards compatibility. * It now returns the same value as getDescription (i.e. any file names * that may have been associated with an object can now be found in the * description attribute). * @deprecated **/ AREXPORT const char *getFileName(void) const; private: /// Parses the given arguments and sets the description of the given ArMapObject static bool setObjectDescription(ArMapObject *object, ArArgumentBuilder *arg); protected: /// The type of the map object std::string myType; /// If non-empty, then myType ends with "WithHeading" and this is the "root" std::string myBaseType; /// The name of the map object, if any std::string myName; /// The description of the map object std::string myDescription; /// For pose objects, THE pose; For rectangle objects, contains the optional rotation ArPose myPose; /// Reserved for future use std::string myIconName; /// Whether the map object is a region (line or rect) with "from/to" poses bool myHasFromTo; /// The "from" pose of a region map object; valid only if myHasFromTo is true ArPose myFromPose; /// The "to" pose of a region map object; valid only if myHasFromTo is true ArPose myToPose; /// For rectangle objects, the line segments that comprise the perimeter (even if rotated) std::list myFromToSegments; /// For line objects, the line ArLineSegment myFromToSegment; /// Text representation written to the map file mutable std::string myStringRepresentation; }; // end class ArMapObject // ============================================================================= #ifndef SWIG /// Comparator for two pointers to map objects /** @swigomit */ struct ArMapObjectCompare : public std::binary_function { /// Returns true if obj1 is less than obj2; NULL pointers are greater than non-NULL bool operator()(const ArMapObject *obj1, const ArMapObject *obj2) { if ((obj1 != NULL) && (obj2 != NULL)) { return *obj1 < *obj2; } else if ((obj1 == NULL) && (obj2 == NULL)) { return false; } else { return (obj1 == NULL); } } // end operator() }; // end struct ArMapObjectCompare #endif //ifndef SWIG #endif // ARMAPOBJECT_H