wheeledexperimenthelper.cpp
50 const wVector centerOnPlane = wall->matrix().w_pos - wall->matrix().z_ax.scale(wall->sideZ() / 2.0);
87 FARSA_DEBUG_TEST_INVALID(mtr.x_ax.x) FARSA_DEBUG_TEST_INVALID(mtr.x_ax.y) FARSA_DEBUG_TEST_INVALID(mtr.x_ax.z)
91 const wVector vdir = v.scale(1.0 / v.norm()); FARSA_DEBUG_TEST_INVALID(vdir.x) FARSA_DEBUG_TEST_INVALID(vdir.y) FARSA_DEBUG_TEST_INVALID(vdir.z)
93 // To get the angle (unsigned), computing the acos of the dot product of the two vectors. We have to
94 // constrain the cross product between -1 and 1 because sometimes it can have values outside the range
95 const double crossProduct = min(1.0, max(-1.0, mtr.x_ax % vdir)); FARSA_DEBUG_TEST_INVALID(crossProduct)
147 void computeLinearViewFieldOccupiedRangeForCircle(const wMatrix& cameraMtr, const wMatrix& objMtr, double radius, const SegmentColorIt segmentsColorBegin, const SegmentColorIt segmentsColorEnd, QVector<PhyObject2DWrapper::AngularRangeAndColor>& rangesAndColors, double& distance, double maxDistance)
152 // We have to translate the camera to lie on the same plane of the cylinder base. We translate it along
153 // its local upvector (Z axis) until it reaches the plane containing the base of the cylinder. Of course
154 // this only works if the camera Z axis is not paraller to the plane with the base of the cylinder. In
161 mtr.w_pos = mtr.w_pos + mtr.z_ax.scale((objMtr.w_pos.z - mtr.w_pos.z) / mtr.z_ax.z); FARSA_DEBUG_TEST_INVALID(mtr.w_pos.x) FARSA_DEBUG_TEST_INVALID(mtr.w_pos.y) FARSA_DEBUG_TEST_INVALID(mtr.w_pos.z) FARSA_DEBUG_TEST_INVALID(mtr.z_ax.x) FARSA_DEBUG_TEST_INVALID(mtr.z_ax.y) FARSA_DEBUG_TEST_INVALID(mtr.z_ax.z) FARSA_DEBUG_TEST_INVALID(objMtr.w_pos.x) FARSA_DEBUG_TEST_INVALID(objMtr.w_pos.y) FARSA_DEBUG_TEST_INVALID(objMtr.w_pos.z)
163 // First of all we have to calculate the distance between the center of the camera and the center of the
164 // cylinder. Here we also check that the camera is not inside the cylinder. The vector from the camera
165 // to the center of the cylinder is computed in the object frame of reference because we need it in this
179 const double halfSectorAngle = acos(radius / centerDistance); FARSA_DEBUG_TEST_INVALID(halfSectorAngle)
183 const real startAngleInCylinder = normalizeRad(atan2(centerDir.z, centerDir.y) - halfSectorAngle);
186 // Clearing the vector that will contain segments and colors. It will first contain ranges in the
191 rangesAndColors.append(PhyObject2DWrapper::AngularRangeAndColor(startAngleInCylinder, endAngleInCylinder, segmentsColorBegin->color));
196 const Intervals visibleArc = Intervals(SimpleInterval(startAngleInCylinder, endAngleInCylinder)) & SimpleInterval(-PI_GRECO, PI_GRECO);
202 // Computing the intersection between the current segment and the visible range and adding it. We don't
203 // need to intersect the cur segment with [-pi, pi] as we did for visibleArc because the intersection
207 for (Intervals::const_iterator intrvIt = curVisibleSegmentArc.begin(); intrvIt != curVisibleSegmentArc.end(); ++intrvIt) {
208 rangesAndColors.append(PhyObject2DWrapper::AngularRangeAndColor(intrvIt->start, intrvIt->end, it->color));
216 // Getting the points corresponding to the angles in the current range in the frame of reference
218 const wVector startPointCylinder(0.0, radius * cos(rangesAndColors[i].minAngle), radius * sin(rangesAndColors[i].minAngle)); FARSA_DEBUG_TEST_INVALID(startPointCylinder.x) FARSA_DEBUG_TEST_INVALID(startPointCylinder.y) FARSA_DEBUG_TEST_INVALID(startPointCylinder.z)
219 const wVector endPointCylinder(0.0, radius * cos(rangesAndColors[i].maxAngle), radius * sin(rangesAndColors[i].maxAngle)); FARSA_DEBUG_TEST_INVALID(endPointCylinder.x) FARSA_DEBUG_TEST_INVALID(endPointCylinder.y) FARSA_DEBUG_TEST_INVALID(endPointCylinder.z)
222 const wVector startPoint = objMtr.transformVector(startPointCylinder); FARSA_DEBUG_TEST_INVALID(startPoint.x) FARSA_DEBUG_TEST_INVALID(startPoint.y) FARSA_DEBUG_TEST_INVALID(startPoint.z)
223 const wVector endPoint = objMtr.transformVector(endPointCylinder); FARSA_DEBUG_TEST_INVALID(endPoint.x) FARSA_DEBUG_TEST_INVALID(endPoint.y) FARSA_DEBUG_TEST_INVALID(endPoint.z)
225 // Now computing the angles in the linear camera. As we don't know which is the start angle and which
226 // the end angle, we rely on the fact that for cylinders the camera cannot see a portion greater than
227 // PI_GRECO. We also check that the vectors to start and end point are not zero; if they are the angle is
230 const double firstAngleCamera = (fabs(firstAngleVector.norm()) < epsilon) ? getAngleWithXAxis(mtr, objMtr.w_pos - mtr.w_pos) : getAngleWithXAxis(mtr, firstAngleVector); FARSA_DEBUG_TEST_INVALID(firstAngleCamera)
232 const double secondAngleCamera = (fabs(secondAngleVector.norm()) < epsilon) ? getAngleWithXAxis(mtr, objMtr.w_pos - mtr.w_pos) : getAngleWithXAxis(mtr, secondAngleVector); FARSA_DEBUG_TEST_INVALID(secondAngleCamera)
234 // Checking if they are on different sides of the -PI_GRECO/PI_GRECO boundary or on the same side. Here we exploit
244 // Checking if they are on different sides of the -PI_GRECO/PI_GRECO boundary or on the same side. Here we exploit
257 // void computeLinearViewFieldOccupiedRangeForCircle(const wMatrix& cameraMtr, const wMatrix& objMtr, double radius, const QList<PhyCylinder::SegmentColor>& segmentsColor, QVector<PhyObject2DWrapper::AngularRangeAndColor>& rangesAndColors, double& distance, double maxDistance)
259 // // We have to translate the camera to lie on the same plane of the cylinder base. We translate it along
260 // // its local upvector (Z axis) until it reaches the plane containing the base of the cylinder. Of course
261 // // this only works if the camera Z axis is not paraller to the plane with the base of the cylinder. In
270 // // First of all we have to calculate the distance between the center of the camera and the center of the
271 // // cylinder. Here we also check that the camera is not inside the cylinder. The vector from the camera
272 // // to the center of the cylinder is computed in the object frame of reference because we need it in this
290 // const real startAngleInCylinder = normalizeRad(atan2(centerDir.z, centerDir.y) - halfSectorAngle);
293 // // Clearing the vector that will contain segments and colors. It will first contain ranges in the
294 // // cylinder frame of reference, and then the angles will be converted to linear camera ranges
298 // rangesAndColors.append(PhyObject2DWrapper::AngularRangeAndColor(startAngleInCylinder, endAngleInCylinder, segmentsColor[0].color));
303 // const Intervals visibleArc = Intervals(SimpleInterval(startAngleInCylinder, endAngleInCylinder)) & SimpleInterval(-PI_GRECO, PI_GRECO);
309 // // Computing the intersection between the current segment and the visible range and adding it. We don't
310 // // need to intersect the cur segment with [-pi, pi] as we did for visibleArc because the intersection
314 // for (Intervals::const_iterator it = curVisibleSegmentArc.begin(); it != curVisibleSegmentArc.end(); ++it) {
315 // rangesAndColors.append(PhyObject2DWrapper::AngularRangeAndColor(it->start, it->end, segmentsColor[i].color));
323 // // Getting the points corresponding to the angles in the current range in the frame of reference
325 // const wVector startPointCylinder(0.0, radius * cos(rangesAndColors[i].minAngle), radius * sin(rangesAndColors[i].minAngle));
326 // const wVector endPointCylinder(0.0, radius * cos(rangesAndColors[i].maxAngle), radius * sin(rangesAndColors[i].maxAngle));
332 // // Now computing the angles in the linear camera. As we don't know which is the start angle and which the end angle, we
337 // // Checking if they are on different sides of the -PI_GRECO/PI_GRECO boundary or on the same side. Here we exploit
347 // // Checking if they are on different sides of the -PI_GRECO/PI_GRECO boundary or on the same side. Here we exploit
378 void computeDistanceAndOrientationFromRobotToCylinder(wVector robotPosition, double robotOrientation, double robotRadius, double radius, wVector position, double& distance, double& angle)
489 m_vertexes(QVector<wVector>() << computeWallVertex(m_box, 0) << computeWallVertex(m_box, 1) << computeWallVertex(m_box, 2) << computeWallVertex(m_box, 3)),
558 void Box2DWrapper::computeLinearViewFieldOccupiedRange(const wMatrix& cameraMtr, QVector<AngularRangeAndColor>& rangesAndColors, double& distance, double maxDistance) const
562 // If this is a Plane or a RectangularTargetArea, we simply return a negative distance (they are not visible with
569 // We have to translate the camera to lie on the same plane of the vertex. We translate it along
570 // its local upvector (Z axis) until it reaches the plane containing the base of the wall. Of course
571 // this only works if the camera Z axis is not paraller to the plane with the base of the wall. In
591 // Now finding the min and max angle (their indexes). We have to take into account the fact that the
592 // angle with the minimum value could be the upper limit and viceversa because the object could be
593 // behind the camera. However we know that, as the camera is outside the wall, the maximum possible
594 // angular sector of the view filed occupied by the wall is 180°. This means that also the angular
595 // distance of one vertex with the center of the wall must be less than 180°. So, if we compute this
596 // distance and get a value greater than 180°, we have to take (360° - computed_angular_distance)
603 // These two are the angular distances of the current min and max angles from the center. Their initial
649 #warning QUESTO MODO DI CALCOLARE LA DISTANZA È SBAGLIATO (E NON NE CAPISCO IL SENSO), MA È QUELLO USATO IN EVOROBOT, QUINDI PER IL MOMENTO LO USO (ANCHE PERCHÉ USARE LA DISTANZA PER L OCCLUSIONE NON VA BENE COMUNQUE)
654 distance = ((mtr.w_pos - m_vertexes[minAngleID]).norm() + (mtr.w_pos - m_vertexes[maxAngleID]).norm()) / 2.0;
662 bool Box2DWrapper::computeDistanceAndOrientationFromRobot(const WheeledRobot2DWrapper& robot, double& distance, double& angle) const
665 #warning I CALCOLI PER DISTANZA E ORIENTAMENTO IN EVOROBOT SONO STRANI, QUI HO CERCATO DI FARE QUALCOSA CHE MI SEMBRI SENSATO...
678 // Now we can find the point in the rectangle that is nearest to the robot position. As we work in the box
702 // Although distance is independent of the frame of reference, we convert the nearest point to the global frame
704 const wVector nearestPoint = m_box->matrix().transformVector(wVector(nearestX, nearestY, relRobotPosition.z));
706 // Now we can easily compute the distance and orientation. For the distance we have to remove the robot radius
708 const real robotOrientation = (dynamic_cast<const RobotOnPlane*>(robot.wObject()))->orientation(m_arena->getPlane());
709 angle = atan2(nearestPoint.y - robotPosition.y, nearestPoint.x - robotPosition.x) - robotOrientation;
717 m_type(((type != SmallCylinder) && (type != BigCylinder) && (type != CircularTargetArea)) ? Cylinder : type)
774 void Cylinder2DWrapper::computeLinearViewFieldOccupiedRange(const wMatrix& cameraMtr, QVector<AngularRangeAndColor>& rangesAndColors, double& distance, double maxDistance) const
776 // If this is a CircularTargetArea, we simply return a negative distance (it is not visible with
784 computeLinearViewFieldOccupiedRangeForCircle(cameraMtr, m_cylinder->matrix(), m_cylinder->radius(), m_cylinder->segmentsColor().constBegin(), m_cylinder->segmentsColor().constEnd(), rangesAndColors, distance, maxDistance);
787 bool Cylinder2DWrapper::computeDistanceAndOrientationFromRobot(const WheeledRobot2DWrapper& robot, double& distance, double& angle) const
794 const double robotOrientation = (dynamic_cast<const RobotOnPlane*>(robot.wObject()))->orientation(m_arena->getPlane());
795 computeDistanceAndOrientationFromRobotToCylinder(robot.position(), robotOrientation, robot.getRadius(), m_cylinder->radius(), m_cylinder->matrix().w_pos, distance, angle);
849 void Sphere2DWrapper::computeLinearViewFieldOccupiedRange(const wMatrix& /*cameraMtr*/, QVector<AngularRangeAndColor>& /*rangesAndColors*/, double& distance, double /*maxDistance*/) const
856 bool Sphere2DWrapper::computeDistanceAndOrientationFromRobot(const WheeledRobot2DWrapper& robot, double& distance, double& angle) const
865 const double robotOrientation = (dynamic_cast<const RobotOnPlane*>(robot.wObject()))->orientation(m_arena->getPlane());
871 WheeledRobot2DWrapper::WheeledRobot2DWrapper(Arena* arena, RobotOnPlane* robot, double height, double radius) :
928 void WheeledRobot2DWrapper::computeLinearViewFieldOccupiedRange(const wMatrix& cameraMtr, QVector<AngularRangeAndColor>& rangesAndColors, double& distance, double maxDistance) const
930 const wMatrix mtr = wObject()->matrix().rotateAround(wObject()->matrix().y_ax, wObject()->matrix().w_pos, -PI_GRECO / 2.0);
932 // Getting the vector with cylinder colors. For the moment only the MarXbot can have multiple colors
934 #warning QUESTA ROBA È BRUTTA, IL CODICE PER LE SIMULAZIONI CON I WHEELED SI STA INGARBUGLIANDO...
944 computeLinearViewFieldOccupiedRangeForCircle(cameraMtr, mtr, m_radius, &s, (&s + 1), rangesAndColors, distance, maxDistance);
946 computeLinearViewFieldOccupiedRangeForCircle(cameraMtr, mtr, m_radius, epuck->segmentsColor().constBegin(), epuck->segmentsColor().constEnd(), rangesAndColors, distance, maxDistance);
949 computeLinearViewFieldOccupiedRangeForCircle(cameraMtr, mtr, m_radius, marxbot->segmentsColor().constBegin(), marxbot->segmentsColor().constEnd(), rangesAndColors, distance, maxDistance);
953 bool WheeledRobot2DWrapper::computeDistanceAndOrientationFromRobot(const WheeledRobot2DWrapper& robot, double& distance, double& angle) const
959 const double robotOrientation = (dynamic_cast<const RobotOnPlane*>(robot.wObject()))->orientation(m_arena->getPlane());
960 computeDistanceAndOrientationFromRobotToCylinder(robot.position(), robotOrientation, robot.getRadius(), m_radius, position(), distance, angle);
992 // Taking the two x axes. We can take the x axis of mtr1 as is, while we need to project the X axis
993 // of mtr2 onto the XY plane of mtr1. To do so we simply project the x axis of mtr2 on the z axis of
1005 // Now choosing the right sign. To do this we first compute the cross product of the two x axes and
virtual bool computeDistanceAndOrientationFromRobot(const WheeledRobot2DWrapper &robot, double &distance, double &angle) const
Computes the distance and orientation of this object respect to the given robot.
Definition: wheeledexperimenthelper.cpp:953
virtual PhySphere * phyObject()
Returns a pointer to the wrapped PhyObject.
Definition: wheeledexperimenthelper.cpp:814
bool getKinematic() const
virtual Type type() const
Returns the type of this wrapper object.
Definition: wheeledexperimenthelper.cpp:515
void setKinematic(bool b, bool c=false)
void setUseColorTextureOfOwner(bool b)
Sets whether this will be rendered with the color and texture of our owner (if we have one) ...
Definition: wheeledexperimenthelper.cpp:476
Cylinder2DWrapper(Arena *arena, PhyCylinder *cylinder, Type type)
Constructor.
Definition: wheeledexperimenthelper.cpp:714
FARSA_UTIL_TEMPLATE real normalizeRad(real x)
QColor color() const
Returns the color to use when rendering this.
Definition: wheeledexperimenthelper.cpp:471
void setUseColorTextureOfOwner(bool b)
The subclass of PhyObject2DWrapper wrapping a box.
Definition: wheeledexperimenthelper.h:390
double getRadius() const
Returns the radius of the robot.
Definition: wheeledexperimenthelper.h:1023
void setTexture(QString textureName)
Set the texture to use when rendering this.
Definition: wheeledexperimenthelper.cpp:456
const QList< PhyCylinder::SegmentColor > & segmentsColor() const
The subclass of PhyObject2DWrapper wrapping a wheeled robot.
Definition: wheeledexperimenthelper.h:896
QColor color() const
real sideZ() const
WheeledRobot2DWrapper(Arena *arena, RobotOnPlane *robot, double height, double radius)
Constructor.
Definition: wheeledexperimenthelper.cpp:871
virtual Type type() const
Returns the type of this wrapper object.
Definition: wheeledexperimenthelper.cpp:834
bool getStatic() const
virtual bool computeDistanceAndOrientationFromRobot(const WheeledRobot2DWrapper &robot, double &distance, double &angle) const
Computes the distance and orientation of this object respect to the given robot.
Definition: wheeledexperimenthelper.cpp:787
virtual PhyCylinder * phyObject()
Returns a pointer to the wrapped PhyObject.
Definition: wheeledexperimenthelper.cpp:729
virtual void setStatic(bool s)
Sets whether the object is static or not.
Definition: wheeledexperimenthelper.cpp:739
virtual void setStatic(bool s)
Sets whether the object is static or not.
Definition: wheeledexperimenthelper.cpp:414
void setTexture(QString textureName)
virtual void computeLinearViewFieldOccupiedRange(const wMatrix &cameraMtr, QVector< AngularRangeAndColor > &rangesAndColors, double &distance, double maxDistance) const
Computes the portion of a linear the view field occupied by this object.
Definition: wheeledexperimenthelper.cpp:928
virtual WObject * wObject()
Returns a pointer to the wrapped object.
Definition: wheeledexperimenthelper.cpp:404
FARSA_UTIL_TEMPLATE const T max(const T &t1, const U &t2)
wVector position() const
Returns the position of the object.
Definition: wheeledexperimenthelper.cpp:451
virtual bool computeDistanceAndOrientationFromRobot(const WheeledRobot2DWrapper &robot, double &distance, double &angle) const
Computes the distance and orientation of this object respect to the given robot.
Definition: wheeledexperimenthelper.cpp:662
void setColor(QColor c)
real radius() const
const QList< PhyCylinder::SegmentColor > & segmentsColor() const
virtual void setPosition(real x, real y)
Sets the position of the object in the plane.
Definition: wheeledexperimenthelper.cpp:918
bool useColorTextureOfOwner() const
Returns whether this will be rendered with the color and texture of the owner (if we have one) ...
Definition: wheeledexperimenthelper.cpp:481
virtual PhyObject * phyObject()
Returns a pointer to the wrapped PhyObject.
Definition: wheeledexperimenthelper.cpp:903
real sideX() const
bool getStatic() const
Returns true if the object is static.
Definition: wheeledexperimenthelper.cpp:421
virtual bool computeDistanceAndOrientationFromRobot(const WheeledRobot2DWrapper &robot, double &distance, double &angle) const
Computes the distance and orientation of this object respect to the given robot.
Definition: wheeledexperimenthelper.cpp:856
virtual void computeLinearViewFieldOccupiedRange(const wMatrix &cameraMtr, QVector< AngularRangeAndColor > &rangesAndColors, double &distance, double maxDistance) const
Computes the portion of a linear the view field occupied by this object.
Definition: wheeledexperimenthelper.cpp:849
const wMatrix & matrix() const
real radius() const
virtual Type type() const
Returns the type of this wrapped object.
Definition: wheeledexperimenthelper.cpp:913
virtual void setKinematic(bool b, bool c=false)
Sets whether the object is kinematic or not.
Definition: wheeledexperimenthelper.cpp:829
virtual void computeLinearViewFieldOccupiedRange(const wMatrix &cameraMtr, QVector< AngularRangeAndColor > &rangesAndColors, double &distance, double maxDistance) const
Computes the portion of a linear the view field occupied by this object.
Definition: wheeledexperimenthelper.cpp:558
A class wrapping a PhyObject to add methods suitable for wheeled robots simulations.
Definition: wheeledexperimenthelper.h:51
void setPosition(const wVector &newpos)
virtual void setPosition(real x, real y)
Sets the position of the object in the plane.
Definition: wheeledexperimenthelper.cpp:839
real sideY() const
bool useColorTextureOfOwner() const
wMatrix rotateAround(const wVector &axis, const wVector ¢re, real angle) const
The structure with angular range and color used by the computeLinearViewFieldOccupiedRange() function...
Definition: wheeledexperimenthelper.h:75
virtual WObject * wObject()
Returns a pointer to the wrapped object.
Definition: wheeledexperimenthelper.cpp:893
virtual void setStatic(bool s)
Sets whether the object is static or not.
Definition: wheeledexperimenthelper.cpp:824
wVector untransformVector(const wVector &v) const
const QList< SegmentColor > & segmentsColor() const
void setColor(QColor color)
Sets the color to use when rendering this.
Definition: wheeledexperimenthelper.cpp:466
void setStatic(bool b)
virtual void setStatic(bool s)
Sets whether the object is static or not.
Definition: wheeledexperimenthelper.cpp:520
float real
virtual void setKinematic(bool b, bool c=false)
Sets whether the object is kinematic or not.
Definition: wheeledexperimenthelper.cpp:530
QString texture() const
QLinkedList< SimpleInterval >::const_iterator const_iterator
virtual void computeLinearViewFieldOccupiedRange(const wMatrix &cameraMtr, QVector< AngularRangeAndColor > &rangesAndColors, double &distance, double maxDistance) const
Computes the portion of a linear the view field occupied by this object.
Definition: wheeledexperimenthelper.cpp:774
QString texture() const
Returns the name of the texture.
Definition: wheeledexperimenthelper.cpp:461
RobotOnPlane * robotOnPlane()
Returns a pointer to the wrapped object as a RobotOnPlane.
Definition: wheeledexperimenthelper.cpp:883
virtual void setKinematic(bool b, bool c=false)
Sets whether the object is kinematic or not.
Definition: wheeledexperimenthelper.cpp:749
virtual void setKinematic(bool b, bool c=false)
Sets whether the object is kinematic or not.
Definition: wheeledexperimenthelper.cpp:430
FARSA_UTIL_TEMPLATE const T min(const T &t1, const U &t2)
bool getKinematic() const
Returns true if the object has kinematic behaviour.
Definition: wheeledexperimenthelper.cpp:437
virtual PhyObject * phyObject()=0
Returns a pointer to the wrapped PhyObject.
Arena *const m_arena
The pointer to the arena in which this object lives.
Definition: wheeledexperimenthelper.h:355
void setPosition(wVector pos)
Sets the position of the object in the plane.
Definition: wheeledexperimenthelper.cpp:446
virtual Type type() const
Returns the type of this wrapper object.
Definition: wheeledexperimenthelper.cpp:759
Sphere2DWrapper(Arena *arena, PhySphere *sphere, Type type)
Constructor.
Definition: wheeledexperimenthelper.cpp:801
Box2DWrapper(Arena *arena, PhyBox *box, Type type)
Constructor.
Definition: wheeledexperimenthelper.cpp:486
wVector transformVector(const wVector &v) const
virtual PhyBox * phyObject()
Returns a pointer to the wrapped PhyObject.
Definition: wheeledexperimenthelper.cpp:505
virtual void setPosition(real x, real y)
Sets the position of the object in the plane.
Definition: wheeledexperimenthelper.cpp:537
virtual void setPosition(real x, real y)
Sets the position of the object in the plane.
Definition: wheeledexperimenthelper.cpp:764