8 #include <argos3/core/simulator/simulator.h>
9 #include <argos3/core/simulator/space/space.h>
10 #include <argos3/core/simulator/loop_functions.h>
12 #ifdef ARGOS_WITH_FREEIMAGE
13 #include <FreeImagePlus.h>
21 #ifdef ARGOS_WITH_FREEIMAGE
22 class CFloorColorFromImageFile :
public CFloorEntity::CFloorColorSource {
26 CFloorColorFromImageFile(
const std::string& str_path) {
29 cArenaSize.GetX() * 0.5f,
30 cArenaSize.GetY() * 0.5f);
32 m_cArenaCenter.
Set(cArenaCenter.GetX(),
37 virtual void Reset() {
38 LoadImage(m_strImageFileName);
41 virtual CColor GetColorAtPoint(
Real f_x,
44 UInt32 x =
static_cast<UInt32>((f_x + m_cHalfArenaSize.GetX()) * m_fArenaToImageCoordinateXFactor);
45 UInt32 y =
static_cast<UInt32>((f_y + m_cHalfArenaSize.GetY()) * m_fArenaToImageCoordinateYFactor);
47 if(m_cImage.getBitsPerPixel() <= 8) {
48 RGBQUAD* ptColorPalette;
51 if(! m_cImage.getPixelIndex(x, y, &tPixelIndex)) {
53 "). Image size (" << m_cImage.getWidth() <<
"," <<
54 m_cImage.getHeight() <<
")");
56 ptColorPalette = m_cImage.getPalette();
57 return CColor(ptColorPalette[tPixelIndex].rgbRed,
58 ptColorPalette[tPixelIndex].rgbGreen,
59 ptColorPalette[tPixelIndex].rgbBlue);
64 if(! m_cImage.getPixelColor(x, y, &tColorPixel)) {
66 "). Image size (" << m_cImage.getWidth() <<
"," <<
67 m_cImage.getHeight() <<
")");
69 return CColor(tColorPixel.rgbRed,
75 virtual void SaveAsImage(
const std::string& str_path) {
76 m_strImageFileName = str_path;
77 m_cImage.save(str_path.c_str());
80 virtual const std::string& GetImageFileName()
const {
81 return m_strImageFileName;
86 void LoadImage(
const std::string& str_path) {
87 m_strImageFileName = str_path;
88 if(!m_cImage.load(m_strImageFileName.c_str())) {
94 m_fArenaToImageCoordinateXFactor = m_cImage.getWidth() / cArenaSize.
GetX();
95 m_fArenaToImageCoordinateYFactor = m_cImage.getHeight() / cArenaSize.GetY();
101 Real m_fArenaToImageCoordinateXFactor;
102 Real m_fArenaToImageCoordinateYFactor;
103 CVector2 m_cHalfArenaSize;
104 CVector2 m_cArenaCenter;
105 std::string m_strImageFileName;
118 m_cLoopFunctions(
CSimulator::GetInstance().GetLoopFunctions()),
119 m_unPixelsPerMeter(un_pixels_per_meter) {
121 m_cHalfArenaSize.
Set(
122 cArenaSize.
GetX() * 0.5f,
123 cArenaSize.
GetY() * 0.5f);
125 m_cArenaCenter.
Set(cArenaCenter.
GetX(),
126 cArenaCenter.
GetY());
134 #ifdef ARGOS_WITH_FREEIMAGE
135 virtual void SaveAsImage(
const std::string& str_path) {
136 fipImage cImage(FIT_BITMAP,
137 static_cast<UInt32>(m_unPixelsPerMeter * m_cHalfArenaSize.
GetX()*2),
138 static_cast<UInt32>(m_unPixelsPerMeter * m_cHalfArenaSize.
GetY()*2), 24);
139 Real fFactor = 1.0f /
static_cast<Real>(m_unPixelsPerMeter);
143 for(
UInt32 y = 0; y < cImage.getHeight(); ++y) {
144 for(
UInt32 x = 0; x < cImage.getWidth(); ++x) {
145 cFloorPos.
Set(x * fFactor, y * fFactor);
146 cFloorPos -= m_cHalfArenaSize;
147 cFloorPos += m_cArenaCenter;
149 tFIPPixel.rgbRed = cARGoSPixel.
GetRed();
150 tFIPPixel.rgbGreen = cARGoSPixel.
GetGreen();
151 tFIPPixel.rgbBlue = cARGoSPixel.
GetBlue();
152 cImage.setPixelColor(x, y, &tFIPPixel);
155 if(!cImage.save(str_path.c_str())) {
163 CLoopFunctions& m_cLoopFunctions;
164 UInt32 m_unPixelsPerMeter;
165 CVector2 m_cHalfArenaSize;
166 CVector2 m_cArenaCenter;
174 m_eColorSource(UNSET),
175 m_pcColorSource(nullptr),
176 m_bHasChanged(true) {}
181 #ifdef ARGOS_WITH_FREEIMAGE
183 const std::string& str_file_name) :
185 m_eColorSource(FROM_IMAGE),
186 m_pcColorSource(nullptr),
187 m_bHasChanged(true) {
188 std::string strFileName = str_file_name;
190 m_pcColorSource =
new CFloorColorFromImageFile(strFileName);
198 UInt32 un_pixels_per_meter) :
200 m_eColorSource(FROM_LOOP_FUNCTIONS),
202 m_bHasChanged(true) {}
208 if(m_pcColorSource !=
nullptr) {
209 delete m_pcColorSource;
220 std::string strColorSource;
222 if(strColorSource ==
"loop_functions") {
228 else if(strColorSource ==
"image") {
229 #ifdef ARGOS_WITH_FREEIMAGE
234 m_pcColorSource =
new CFloorColorFromImageFile(strPath);
236 THROW_ARGOSEXCEPTION(
"ARGoS was compiled without FreeImage, this image source is unsupported for the floor entity \"" <<
244 "\" for the floor entity \"" <<
254 m_pcColorSource->
Reset();
260 #ifdef ARGOS_WITH_FREEIMAGE
261 void CFloorEntity::SaveAsImage(
const std::string& str_path) {
262 m_pcColorSource->SaveAsImage(str_path);
271 "Carlo Pinciroli [ilpincy@gmail.com]",
273 "It contains the properties of the arena floor.",
274 "The floor entity contains the properties of the arena floor. In the current\n"
275 "implementation, it contains only the color of the floor. The floor color is\n"
276 "detected by the robots' ground sensors.\n\n"
277 "REQUIRED XML CONFIGURATION\n\n"
280 " <floor id=\"floor\"\n"
281 " source=\"SOURCE\" />\n"
284 "The 'id' attribute is necessary and must be unique among the entities. If two\n"
285 "entities share the same id, initialization aborts.\n"
286 "The 'source' attribute specifies where to get the color of the floor from. Its\n"
287 "value, here denoted as SOURCE, can assume the following values:\n\n"
288 " image The color is calculated from the passed image file\n"
289 " loop_functions The color is calculated calling the loop functions\n\n"
290 "When 'source' is set to 'image', as showed in the following example, you have\n"
291 "to specify the image path in the additional attribute 'path':\n\n"
294 " <floor id=\"floor\"\n"
295 " source=\"image\"\n"
296 " path=\"/path/to/imagefile.ext\" />\n"
299 "Many image formats are available, such as PNG, JPG, BMP, GIF and many more.\n"
300 "Refer to the FreeImage webpage for a complete list of supported image formats\n"
301 "(http://freeimage.sourceforge.net/features.html).\n\n"
302 "When 'source' is set to 'loop_functions', as showed in the following example,\n"
303 "an image is implicitly created to be used as texture for graphical\n"
304 "visualizations. The algorithm that creates the texture needs to convert from\n"
305 "meters (in the arena) to pixels (of the texture). You control how many pixels\n"
306 "per meter are used with the attribute 'pixels_per_meter'. Clearly, the higher\n"
307 "value, the higher the quality, but also the slower the algorithm and the bigger\n"
308 "the texture. The algorithm is called only once at init time, so the fact that\n"
309 "it is slow is not so important. However, the image size is limited by OpenGL.\n"
310 "Every implementation has its own limit, and you should check yours if any\n"
311 "texture-related problem arises. Now for the example:\n\n"
314 " <floor id=\"floor\"\n"
315 " source=\"loop_functions\"\n"
316 " pixels_per_meter=\"100\" />\n"
319 "OPTIONAL XML CONFIGURATION\n\n"
320 "None for the time being.\n",
#define THROW_ARGOSEXCEPTION(message)
This macro throws an ARGoS exception with the passed message.
unsigned int UInt32
32-bit unsigned integer.
float Real
Collects all ARGoS code.
The namespace containing all the ARGoS related code.
std::string & ExpandEnvVariables(std::string &str_buffer)
Searches into str_buffer for occurrences of an environment variable of the form $VAR and substitutes ...
ticpp::Element TConfigurationNode
The ARGoS configuration XML node.
REGISTER_SPACE_OPERATION(CSpaceOperationAddEntity, CSpaceOperationAddCFloorEntity, CFloorEntity)
REGISTER_STANDARD_SPACE_OPERATION_REMOVE_ENTITY(CFloorEntity)
void GetNodeAttribute(TConfigurationNode &t_node, const std::string &str_attribute, T &t_buffer)
Returns the value of a node's attribute.
REGISTER_ENTITY(CFloorEntity, "floor", "Carlo Pinciroli [ilpincy@gmail.com]", "1.0", "It contains the properties of the arena floor.", "The floor entity contains the properties of the arena floor. In the current\n" "implementation, it contains only the color of the floor. The floor color is\n" "detected by the robots' ground sensors.\n\n" "REQUIRED XML CONFIGURATION\n\n" " <arena ...>\n" " ...\n" " <floor id=\"floor\"\n" " source=\"SOURCE\" />\n" " ...\n" " </arena>\n\n" "The 'id' attribute is necessary and must be unique among the entities. If two\n" "entities share the same id, initialization aborts.\n" "The 'source' attribute specifies where to get the color of the floor from. Its\n" "value, here denoted as SOURCE, can assume the following values:\n\n" " image The color is calculated from the passed image file\n" " loop_functions The color is calculated calling the loop functions\n\n" "When 'source' is set to 'image', as showed in the following example, you have\n" "to specify the image path in the additional attribute 'path':\n\n" " <arena ...>\n" " ...\n" " <floor id=\"floor\"\n" " source=\"image\"\n" " path=\"/path/to/imagefile.ext\" />\n" " ...\n" " </arena>\n\n" "Many image formats are available, such as PNG, JPG, BMP, GIF and many more.\n" "Refer to the FreeImage webpage for a complete list of supported image formats\n" "(http://freeimage.sourceforge.net/features.html).\n\n" "When 'source' is set to 'loop_functions', as showed in the following example,\n" "an image is implicitly created to be used as texture for graphical\n" "visualizations. The algorithm that creates the texture needs to convert from\n" "meters (in the arena) to pixels (of the texture). You control how many pixels\n" "per meter are used with the attribute 'pixels_per_meter'. Clearly, the higher\n" "value, the higher the quality, but also the slower the algorithm and the bigger\n" "the texture. The algorithm is called only once at init time, so the fact that\n" "it is slow is not so important. However, the image size is limited by OpenGL.\n" "Every implementation has its own limit, and you should check yours if any\n" "texture-related problem arises. Now for the example:\n\n" " <arena ...>\n" " ...\n" " <floor id=\"floor\"\n" " source=\"loop_functions\"\n" " pixels_per_meter=\"100\" />\n" " ...\n" " </arena>\n\n" "OPTIONAL XML CONFIGURATION\n\n" "None for the time being.\n", "Usable")
const std::string & GetId() const
Returns the id of this entity.
virtual void Init(TConfigurationNode &t_tree)
Initializes the state of the entity from the XML configuration tree.
CFloorColorFromLoopFunctions(UInt32 un_pixels_per_meter)
virtual CColor GetColorAtPoint(Real f_x, Real f_y)
void ApplyTo(CSpace &c_space, CFloorEntity &c_entity)
virtual void Reset()
Restores the initial state of the floor.
CFloorEntity()
Class constructor.
virtual void Init(TConfigurationNode &t_tree)
Initializes the entity from an XML tree.
virtual ~CFloorEntity()
Class destructor.
virtual CColor GetFloorColor(const CVector2 &c_pos_on_floor)
Returns the color of the floor in the specified point.
CSpace & GetSpace() const
Returns a reference to the simulated space.
static CSimulator & GetInstance()
Returns the instance to the CSimulator class.
void SetFloorEntity(CFloorEntity &c_floor_entity)
Sets the floor entity.
void AddEntity(ENTITY &c_entity)
Adds an entity of the given type.
const CVector3 & GetArenaSize() const
Returns the arena size.
const CVector3 & GetArenaCenter() const
Returns the arena center.
UInt8 GetBlue() const
Returns the blue channel of the color.
UInt8 GetGreen() const
Returns the green channel of the color.
UInt8 GetRed() const
Returns the red channel of the color.
Real GetY() const
Returns the y coordinate of this vector.
void Set(Real f_x, Real f_y)
Sets the vector contents from Cartesian coordinates.
Real GetX() const
Returns the x coordinate of this vector.
Real GetX() const
Returns the x coordinate of this vector.
void Set(const Real f_x, const Real f_y, const Real f_z)
Sets the vector contents from Cartesian coordinates.
Real GetY() const
Returns the y coordinate of this vector.