arenaelement.cpp
Go to the documentation of this file.
1 #include "arena.h"
2 #include "arenaelement.h"
3 #include "arenaelementtype.h"
4 #include "xmlloadingexception.h"
5 
6 #include <QList>
7 #include <QDebug>
8 
9 #include <math.h>
10 
11 ArenaElement::ArenaElement(const ArenaElementType * const type, int id)
12  : m_type(type)
13  , m_rotation(0)
14  , m_instanceId(id)
15  , m_itemMountPoint(-1)
16 {
17 }
18 
20 {
22 }
23 
25 {
27 }
28 
30 {
32 }
33 
35 {
37 }
38 
40 {
41  // Do not ignore if pos is same as before! We always have to emit posChanged().
42  //if (pos == m_pos)
43  // return;
44  m_pos = pos;
45  emit posChanged(this, pos);
46  emit modified(this);
47 }
48 
49 void ArenaElement::setItemOffset(const QPointF &offset)
50 {
51  m_itemOffset = offset;
52  emit posChanged(this, m_pos);
53 }
54 
56 {
57  // Do not ignore if rotation is same as before! We always have to emit rotationChanged().
58  //if (rotation == m_rotation)
59  // return;
60  // normalize also negative number (-2 % 3 == -2 but should be 1)
61  // (-2 % 3 + 3) % 3 == (-2 + 3) % 3 == 1
62  int normalizedRotation = (rotation % 360 + 360) % 360;
63  m_rotation = normalizedRotation;
64  emit rotationChanged(this, normalizedRotation);
65  emit modified(this);
66 }
67 
68 void ArenaElement::setItemMountPoint(int mountPoint)
69 {
70  m_itemMountPoint = mountPoint;
71  emit modified(this);
72 }
73 
74 void ArenaElement::load(const QDomElement& node)
75 {
76  if (!node.hasAttribute("x"))
77  throw XmlLoadingException("An arena element is missing an x coordinate.", node);
78  if (!node.hasAttribute("y"))
79  throw XmlLoadingException("An arena element is missing a y coordinate.", node);
80 
81  QPoint pos;
82  pos.setX(node.attribute("x").toInt());
83  pos.setY(node.attribute("y").toInt());
84  setPos(pos);
85 
86  if (node.hasAttribute("offset-x") && node.hasAttribute("offset-y"))
87  {
88  QString offsetX = node.attribute("offset-x");
89  QString offsetY = node.attribute("offset-y");
90 
91  QPointF offset = QPointF(offsetX.toFloat(), offsetY.toFloat());
92  setItemOffset(offset);
93  }
94 
95  if (node.hasAttribute("rotation"))
96  {
97  QString rotation = node.attribute("rotation");
98  setRotation(rotation.toInt());
99  }
100 
101  if (node.hasAttribute("mount-point"))
102  {
103  QString mountPointIndex = node.attribute("mount-point");
104  setItemMountPoint(mountPointIndex.toInt());
105  }
106 }
107 
108 void ArenaElement::save(QXmlStreamWriter& writer)
109 {
110  writer.writeStartElement("element");
111  writer.writeAttribute("type", m_type->name());
112  writer.writeAttribute("rotation", QString::number(rotation()));
113  writer.writeAttribute("x", QString::number(m_pos.x()));
114  writer.writeAttribute("y", QString::number(m_pos.y()));
115 
116  if (!m_itemOffset.isNull())
117  {
118  writer.writeAttribute("offset-x", QString::number(m_itemOffset.x()));
119  writer.writeAttribute("offset-y", QString::number(m_itemOffset.y()));
120  }
121  if (m_itemMountPoint != -1)
122  writer.writeAttribute("mount-point", QString::number(m_itemMountPoint));
123  writer.writeEndElement();
124 }
125 
126 void ArenaElement::saveWorld(QXmlStreamWriter& writer)
127 {
128  writer.writeStartElement("model:physical");
129  QString name;
130  QTextStream(&name) << m_type->name() << "_" << m_instanceId;
131  writer.writeAttribute("name", name);
132 
133  ArenaElement *context = m_arena->contextElement(this);
134  QList<ItemMountPoint> contextItemMountPoints;
135  if (context)
136  contextItemMountPoints = context->type()->itemMountPoints();
137 
138  // Use "corrected" mount point index
140  if (!isMountableItem() || !context)
141  {
142  itemMountPoint = -1;
143  }
144  else
145  {
146  // When there are possible mount points, use the first if none is assigned
147  itemMountPoint = qMax(itemMountPoint, 0);
148  // But make sure the index doesn't exceed the last mount point
149  if (contextItemMountPoints.count() <= itemMountPoint)
150  itemMountPoint = -1;
151  }
152 
153  qreal offsetX = 0;
154  qreal offsetZ = 0;
155  if (itemMountPoint >= 0)
156  {
157  Q_ASSERT(context);
158  Q_ASSERT(contextItemMountPoints.count() > itemMountPoint);
159  ItemMountPoint mountPoint = contextItemMountPoints[itemMountPoint];
160  offsetX = mountPoint.second.x() - 0.6;
161  offsetZ = mountPoint.second.y();
162  }
163 
164  QTransform trans;
165  trans.rotate(-m_rotation);
166  QPointF mappedOffset = trans.map(QPointF(offsetX, 0));
167  mappedOffset += m_itemOffset * 1.2;
168 
169  QString xyz;
170  // One unit is 1.2 meters, gazebo is set up to think in meters
171  QTextStream(&xyz) << m_pos.x() * 1.2 + mappedOffset.x() << " "
172  << m_pos.y() * 1.2 + mappedOffset.y() << " " << offsetZ;
173  writer.writeTextElement("xyz", xyz);
174  QString rpy;
175  QTextStream(&rpy) << "0 0 " << -m_rotation;
176  writer.writeTextElement("rpy", rpy);
177  writer.writeTextElement("static", "true");
178 
179  writer.writeStartElement("body:trimesh");
180  writer.writeAttribute("name", name + "_body");
181 
182  writer.writeStartElement("geom:trimesh");
183  writer.writeAttribute("name", name + "_geom");
184 
185  writer.writeTextElement("mesh", m_type->mesh());
186  writer.writeTextElement("scale", "1.0 1.0 1.0");
188  writer.writeTextElement("genTexCoord", "true");
189 
190  writer.writeStartElement("visual");
191  writer.writeTextElement("scale", "1.0 1.0 1.0");
192  writer.writeTextElement("rpy", "0 0 0");
193  writer.writeTextElement("mesh", m_type->mesh());
194  //writer.writeTextElement("material", "Gazebo/WoodPallet");
195  // visual
196  writer.writeEndElement();
197 
198  // geom:trimesh
199  writer.writeEndElement();
200 
201  // body:trimesh
202  writer.writeEndElement();
203 
204  // model:physical
205  writer.writeEndElement();
206 }
207 
208 void ArenaElement::saveWorldSdf(QXmlStreamWriter& writer)
209 {
210  writer.writeStartElement("model");
211  QString name;
212  QTextStream(&name) << m_type->name() << "_" << m_instanceId;
213  writer.writeAttribute("name", name);
214  writer.writeTextElement("static", "true");
215 
216  ArenaElement *context = m_arena->contextElement(this);
217  QList<ItemMountPoint> contextItemMountPoints;
218  if (context)
219  contextItemMountPoints = context->type()->itemMountPoints();
220 
221  // Use "corrected" mount point index
223  if (!isMountableItem() || !context)
224  {
225  itemMountPoint = -1;
226  }
227  else
228  {
229  // When there are possible mount points, use the first if none is assigned
230  itemMountPoint = qMax(itemMountPoint, 0);
231  // But make sure the index doesn't exceed the last mount point
232  if (contextItemMountPoints.count() <= itemMountPoint)
233  itemMountPoint = -1;
234  }
235 
236  qreal offsetX = 0;
237  qreal offsetZ = 0;
238  if (itemMountPoint >= 0)
239  {
240  Q_ASSERT(context);
241  Q_ASSERT(contextItemMountPoints.count() > itemMountPoint);
242  ItemMountPoint mountPoint = contextItemMountPoints[itemMountPoint];
243  offsetX = mountPoint.second.x() - 0.6;
244  offsetZ = mountPoint.second.y();
245  }
246 
247  QTransform trans;
248  trans.rotate(-m_rotation);
249  QPointF mappedOffset = trans.map(QPointF(offsetX, 0));
250  mappedOffset += m_itemOffset * 1.2;
251 
252  QString xyz;
253  // One unit is 1.2 meters, gazebo is set up to think in meters
254  QTextStream(&xyz) << m_pos.x() * 1.2 + mappedOffset.x() << " "
255  << m_pos.y() * 1.2 + mappedOffset.y() << " " << offsetZ;
256 
257  QString rpy;
258  QTextStream(&rpy) << "0 0 " << -(m_rotation/180.0)*M_PI;
259  //writer.writeTextElement("rpy", rpy);
260 
261  writer.writeStartElement("link");
262  writer.writeAttribute("name",name+"_link");
263 
264  writer.writeTextElement("pose", xyz + " " + rpy);
265 
266  writer.writeStartElement("collision");
267  writer.writeAttribute("name",name+"_collision");
268 
269  writer.writeStartElement("geometry");
270 
271  writer.writeStartElement("mesh");
272  writer.writeTextElement("uri", "file://" + m_type->mesh());
273  writer.writeTextElement("scale", "1 1 1");
274  writer.writeEndElement(); // mesh
275 
276  writer.writeEndElement(); // geometry
277 
278  writer.writeEndElement(); // collision
279 
280  writer.writeStartElement("visual");
281  writer.writeAttribute("name",name+"_visual");
282  writer.writeTextElement("cast_shadows","false");
283 
284  writer.writeStartElement("geometry");
285 
286  writer.writeStartElement("mesh");
287  writer.writeTextElement("uri", "file://" + m_type->mesh());
288  writer.writeTextElement("scale", "1 1 1");
289  writer.writeEndElement();
290 
291  writer.writeEndElement(); // geometry
292 
293  writer.writeEndElement(); // visual
294 
295  writer.writeEndElement(); // link
296 
297  writer.writeEndElement(); // model
298 
299 }
300 
301 
302 
303 
304 
305 
306 
307 
308 
void saveWorld(QXmlStreamWriter &writer)
Writes .world format-compliant XML.
void saveWorldSdf(QXmlStreamWriter &writer)
Item freely movable within a grid point.
Type type() const
ArenaElementType const * type() const
Definition: arenaelement.h:43
QList< ItemMountPoint > itemMountPoints() const
int m_itemMountPoint
Definition: arenaelement.h:93
Arena * m_arena
Arena this element currently belongs to (exactly one)
Definition: arenaelement.h:83
void setItemMountPoint(int mountPoint)
See itemMountPoint(). Use -1 to set index to "unspecified".
QPoint m_pos
Definition: arenaelement.h:86
int itemMountPoint() const
Definition: arenaelement.h:62
void setItemOffset(const QPointF &offset)
See itemOffset()
bool isItem() const
Convenience method returning true iff. this is an item element (freely movable)
QString mesh() const
QPointF m_itemOffset
See itemOffset()
Definition: arenaelement.h:88
ArenaElement * contextElement(ArenaElement *element) const
Definition: arena.cpp:498
QPair< QString, QPointF > ItemMountPoint
int rotation() const
Returns the rotation in degrees.
Definition: arenaelement.h:26
void save(QXmlStreamWriter &writer)
Serializes this element in XML.
int m_rotation
rotation in degrees (only multiples of 90 degrees)
Definition: arenaelement.h:90
void load(const QDomElement &node)
Deserializes this element from XML.
void setRotation(int rotation)
Sets the rotation in degrees.
ArenaElement(const ArenaElementType *const type, int id)
Only meant for use by ArenaElementType::createInstance()
QPoint pos() const
Returns the position in arena coordinates.
Definition: arenaelement.h:22
void setPos(QPoint pos)
Sets the position in arena coordinates.
void rotationChanged(ArenaElement *element, int rotation)
void posChanged(ArenaElement *element, QPoint pos)
bool isFloor() const
Convenience method returning true iff. this is a floor element.
bool isMountableItem() const
Convenience method returning true iff. this is a mountable-item element.
Item that can be mounted to a wall element.
QString name() const
const int m_instanceId
Unique ID set by ArenaElementType.
Definition: arenaelement.h:95
bool isWall() const
Convenience method returning true iff. this is a wall element.
void modified(ArenaElement *element)
const ArenaElementType *const m_type
Definition: arenaelement.h:85


hector_nist_arena_designer
Author(s): Stefan Kohlbrecher , Johannes Simon
autogenerated on Fri Aug 21 2020 10:45:27