|
From: <yx...@us...> - 2010-03-30 11:33:09
|
Revision: 190
http://simspark.svn.sourceforge.net/simspark/?rev=190&view=rev
Author: yxu
Date: 2010-03-30 11:33:03 +0000 (Tue, 30 Mar 2010)
Log Message:
-----------
Sense lines on the field (the first working version)
Modified Paths:
--------------
trunk/rcssserver3d/data/rsg/agent/nao/soccer.rsg
trunk/rcssserver3d/plugin/soccer/CMakeLists.txt
trunk/rcssserver3d/plugin/soccer/export.cpp
trunk/rcssserver3d/plugin/soccer/restrictedvisionperceptor/restrictedvisionperceptor.cpp
trunk/rcssserver3d/plugin/soccer/restrictedvisionperceptor/restrictedvisionperceptor.h
trunk/rcssserver3d/plugin/soccer/restrictedvisionperceptor/restrictedvisionperceptor_c.cpp
trunk/spark/lib/salt/CMakeLists.txt
Added Paths:
-----------
trunk/rcssserver3d/data/rsg/agent/fieldline.rsg
trunk/rcssserver3d/data/rsg/agent/fieldring.rsg
trunk/rcssserver3d/plugin/soccer/line/
trunk/rcssserver3d/plugin/soccer/line/line.cpp
trunk/rcssserver3d/plugin/soccer/line/line.h
trunk/rcssserver3d/plugin/soccer/line/line_c.cpp
trunk/spark/lib/salt/line2.h
trunk/spark/lib/salt/linesegment2.h
Added: trunk/rcssserver3d/data/rsg/agent/fieldline.rsg
===================================================================
--- trunk/rcssserver3d/data/rsg/agent/fieldline.rsg (rev 0)
+++ trunk/rcssserver3d/data/rsg/agent/fieldline.rsg 2010-03-30 11:33:03 UTC (rev 190)
@@ -0,0 +1,27 @@
+; -*- mode: lisp; -*-
+;
+; create a field line from ($BegX $BegY) to ($EndX $EndY)
+;
+
+(RSG 0 1)
+(
+ (templ $BegX $BegY $EndX $EndY)
+
+ (nd Transform
+ (nd Line
+ (setBeginPoint $BegX $BegY 0)
+ (setEndPoint $EndX $EndY 0)
+ )
+ )
+
+ ;; (def $centerX (eval (eval $BegX + $EndX) / 2.0))
+ ;; (def $centerY (eval (eval $BegY + $EndY) / 2.0))
+ ;; (def $lengthY (eval (eval $EndY - $BegY) / 2.0))
+
+ ;; (nd Transform
+ ;; (setLocalPos $centerX $centerY 0)
+ ;; (nd Box
+ ;; (setExtents 0.1 $lengthY 0.1)
+ ;; )
+ ;; )
+ )
\ No newline at end of file
Added: trunk/rcssserver3d/data/rsg/agent/fieldring.rsg
===================================================================
--- trunk/rcssserver3d/data/rsg/agent/fieldring.rsg (rev 0)
+++ trunk/rcssserver3d/data/rsg/agent/fieldring.rsg 2010-03-30 11:33:03 UTC (rev 190)
@@ -0,0 +1,89 @@
+; -*- mode: lisp; -*-
+;
+; create a field ring with radius $Radius
+;
+
+(RSG 0 1)
+(
+ (templ $Radius)
+
+ (def $px0 1.0)
+ (def $py0 0.0)
+
+ (def $px36 0.80901699437494745)
+ (def $py36 0.58778525229247314)
+
+ (def $px72 0.30901699437494745)
+ (def $py72 0.95105651629515353)
+
+ (def $px108 -0.30901699437494734)
+ (def $py108 0.95105651629515364)
+
+ (def $px144 -0.80901699437494734)
+ (def $py144 0.58778525229247325)
+
+ (def $px180 -1.0)
+ (def $py180 0.0)
+
+ (def $px216 $px144)
+ (def $py216 (eval -1 * $py144))
+
+ (def $px252 $px108)
+ (def $py252 (eval -1 * $py108))
+
+ (def $px288 $px72)
+ (def $py288 (eval -1 * $py72))
+
+ (def $px324 $px36)
+ (def $py324 (eval -1 * $py36))
+
+ (importScene rsg/agent/fieldline.rsg
+ $px0 $py0
+ $px36 $py36
+ )
+
+ (importScene rsg/agent/fieldline.rsg
+ $px36 $py36
+ $px72 $py72
+ )
+
+ (importScene rsg/agent/fieldline.rsg
+ $px72 $py72
+ $px108 $py108
+ )
+
+ (importScene rsg/agent/fieldline.rsg
+ $px108 $py108
+ $px144 $py144
+ )
+
+ (importScene rsg/agent/fieldline.rsg
+ $px144 $py144
+ $px180 $py180
+ )
+
+ (importScene rsg/agent/fieldline.rsg
+ $px180 $py180
+ $px216 $py216
+ )
+
+ (importScene rsg/agent/fieldline.rsg
+ $px216 $py216
+ $px252 $py252
+ )
+
+ (importScene rsg/agent/fieldline.rsg
+ $px252 $py252
+ $px288 $py288
+ )
+
+ (importScene rsg/agent/fieldline.rsg
+ $px288 $py288
+ $px324 $py324
+ )
+
+ (importScene rsg/agent/fieldline.rsg
+ $px324 $py324
+ $px0 $py0
+ )
+ )
Modified: trunk/rcssserver3d/data/rsg/agent/nao/soccer.rsg
===================================================================
--- trunk/rcssserver3d/data/rsg/agent/nao/soccer.rsg 2010-03-28 08:27:22 UTC (rev 189)
+++ trunk/rcssserver3d/data/rsg/agent/nao/soccer.rsg 2010-03-30 11:33:03 UTC (rev 190)
@@ -10,6 +10,8 @@
(def $FieldWidth (eval Soccer.FieldWidth))
(def $FieldHeight (eval Soccer.FieldHeight))
(def $GoalDepth (eval Soccer.GoalDepth))
+ (def $PenaltyLength (eval Soccer.PenaltyLength))
+ (def $PenaltyWidth (eval Soccer.PenaltyWidth))
;; height of the field ground plane
(def $FieldMaterial matGrass)
@@ -22,6 +24,8 @@
(def $GoalHalfDepth (eval $GoalDepth / 2.0))
(def $FieldLengthTextureSize (eval $FieldLength / 12.0 ))
(def $FieldWidthTextureSize (eval $FieldWidth / 8.0 ))
+ (def $PenaltyX (eval $FieldHalfLength - $PenaltyLength ))
+ (def $PenaltyHalfWidth (eval $PenaltyWidth * 0.5 ))
(def $BorderLength (eval $FieldLength * 0.333))
(def $BorderWidth (eval $FieldWidth * 0.75))
@@ -193,7 +197,72 @@
0
F2R
)
+;;
+;; add field lines
+;;
+;; middle line
+(importScene rsg/agent/fieldline.rsg
+ 0 (eval -1 * $FieldHalfWidth)
+ 0 $FieldHalfWidth
+ )
+;; ground lines
+(importScene rsg/agent/fieldline.rsg
+ $FieldHalfLength (eval -1 * $FieldHalfWidth)
+ $FieldHalfLength $FieldHalfWidth
+ )
+
+(importScene rsg/agent/fieldline.rsg
+ (eval -1 * $FieldHalfLength) (eval -1 * $FieldHalfWidth)
+ (eval -1 * $FieldHalfLength) $FieldHalfWidth
+ )
+
+;; side lines
+(importScene rsg/agent/fieldline.rsg
+ $FieldHalfLength $FieldHalfWidth
+ (eval -1 * $FieldHalfLength) $FieldHalfWidth
+ )
+
+(importScene rsg/agent/fieldline.rsg
+ $FieldHalfLength (eval -1 * $FieldHalfWidth)
+ (eval -1 * $FieldHalfLength) (eval -1 * $FieldHalfWidth)
+ )
+
+;; penalty lines
+(importScene rsg/agent/fieldline.rsg
+ $PenaltyX $PenaltyHalfWidth
+ $PenaltyX (eval -1 * $PenaltyHalfWidth)
+ )
+
+(importScene rsg/agent/fieldline.rsg
+ $PenaltyX $PenaltyHalfWidth
+ $FieldHalfLength $PenaltyHalfWidth
+ )
+
+(importScene rsg/agent/fieldline.rsg
+ $PenaltyX (eval -1 * $PenaltyHalfWidth)
+ $FieldHalfLength (eval -1 * $PenaltyHalfWidth)
+ )
+
+(importScene rsg/agent/fieldline.rsg
+ (eval -1 * $PenaltyX) $PenaltyHalfWidth
+ (eval -1 * $PenaltyX) (eval -1 * $PenaltyHalfWidth)
+ )
+
+(importScene rsg/agent/fieldline.rsg
+ (eval -1 * $PenaltyX) $PenaltyHalfWidth
+ (eval -1 * $FieldHalfLength) $PenaltyHalfWidth
+ )
+
+(importScene rsg/agent/fieldline.rsg
+ (eval -1 * $PenaltyX) (eval -1 * $PenaltyHalfWidth)
+ (eval -1 * $FieldHalfLength) (eval -1 * $PenaltyHalfWidth)
+ )
+
+;; ring
+(importScene rsg/agent/fieldring.rsg
+ 1.8)
+
;;
;; add the ball
;;
Modified: trunk/rcssserver3d/plugin/soccer/CMakeLists.txt
===================================================================
--- trunk/rcssserver3d/plugin/soccer/CMakeLists.txt 2010-03-28 08:27:22 UTC (rev 189)
+++ trunk/rcssserver3d/plugin/soccer/CMakeLists.txt 2010-03-30 11:33:03 UTC (rev 190)
@@ -44,7 +44,8 @@
hmdp_effector/hmdpaction.h
hmdp_effector/hmdpeffector.h
hmdp_effector/hmdpperceptor.h
- hmdp_effector/naospecific.h
+ hmdp_effector/naospecific.h
+ line/line.h
)
set(soccer_LIB_SRCS
@@ -117,6 +118,8 @@
hmdp_effector/hmdpperceptor.cpp
hmdp_effector/hmdpwrapper.cpp
hmdp_effector/naospecific.cpp
+ line/line.cpp
+ line/line_c.cpp
)
include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${FREETYPE_INCLUDE_DIRS}
Modified: trunk/rcssserver3d/plugin/soccer/export.cpp
===================================================================
--- trunk/rcssserver3d/plugin/soccer/export.cpp 2010-03-28 08:27:22 UTC (rev 189)
+++ trunk/rcssserver3d/plugin/soccer/export.cpp 2010-03-30 11:33:03 UTC (rev 190)
@@ -53,6 +53,7 @@
#include "agentintegration/soccerbotbehavior.h"
#include "hmdp_effector/hmdpeffector.h"
#include "hmdp_effector/hmdpperceptor.h"
+#include "line/line.h"
ZEITGEIST_EXPORT_BEGIN()
ZEITGEIST_EXPORT(SoccerControlAspect);
@@ -88,5 +89,6 @@
ZEITGEIST_EXPORT(SoccerbotBehavior);
ZEITGEIST_EXPORT(HMDPPerceptor);
ZEITGEIST_EXPORT(HMDPEffector);
+ ZEITGEIST_EXPORT(Line);
ZEITGEIST_EXPORT_END()
Added: trunk/rcssserver3d/plugin/soccer/line/line.cpp
===================================================================
--- trunk/rcssserver3d/plugin/soccer/line/line.cpp (rev 0)
+++ trunk/rcssserver3d/plugin/soccer/line/line.cpp 2010-03-30 11:33:03 UTC (rev 190)
@@ -0,0 +1,31 @@
+/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*-
+
+ this file is part of rcssserver3D
+ Copyright (C) 2010 RoboCup Soccer Server 3D Maintenance Group
+ $Id$
+
+ 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; version 2 of the License.
+
+ 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "line.h"
+
+Line::Line()
+{
+
+}
+
+Line::~Line()
+{
+
+}
Added: trunk/rcssserver3d/plugin/soccer/line/line.h
===================================================================
--- trunk/rcssserver3d/plugin/soccer/line/line.h (rev 0)
+++ trunk/rcssserver3d/plugin/soccer/line/line.h 2010-03-30 11:33:03 UTC (rev 190)
@@ -0,0 +1,44 @@
+/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*-
+
+ this file is part of rcssserver3D
+ Copyright (C) 2010 RoboCup Soccer Server 3D Maintenance Group
+ $Id$
+
+ 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; version 2 of the License.
+
+ 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+#ifndef LINE_H
+#define LINE_H
+
+#include "../soccernode/soccernode.h"
+
+class Line : public SoccerNode
+{
+public:
+ Line();
+ virtual ~Line();
+
+ salt::Vector3f& BeginPoint() { return mBeginPoint; }
+ salt::Vector3f& EndPoint() { return mEndPoint; }
+ const salt::Vector3f& BeginPoint() const { return mBeginPoint; }
+ const salt::Vector3f& EndPoint() const { return mEndPoint; }
+
+protected:
+
+ salt::Vector3f mBeginPoint;
+ salt::Vector3f mEndPoint;
+};
+
+DECLARE_CLASS(Line);
+
+#endif // LINE_H
Added: trunk/rcssserver3d/plugin/soccer/line/line_c.cpp
===================================================================
--- trunk/rcssserver3d/plugin/soccer/line/line_c.cpp (rev 0)
+++ trunk/rcssserver3d/plugin/soccer/line/line_c.cpp 2010-03-30 11:33:03 UTC (rev 190)
@@ -0,0 +1,65 @@
+/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*-
+
+ this file is part of rcssserver3D
+ Copyright (C) 2010 RoboCup Soccer Server 3D Maintenance Group
+ $Id$
+
+ 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; version 2 of the License.
+
+ 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "line.h"
+
+using namespace boost;
+using namespace oxygen;
+using namespace std;
+
+FUNCTION(Line,setBeginPoint)
+{
+ salt::Vector3f& value = obj->BeginPoint();
+
+ if (
+ (in.GetSize() != 3) ||
+ (! in.GetValue(in[0], value[0])) ||
+ (! in.GetValue(in[1], value[1])) ||
+ (! in.GetValue(in[2], value[2]))
+ )
+ {
+ return false;
+ }
+ return true;
+}
+
+FUNCTION(Line,setEndPoint)
+{
+ salt::Vector3f& value = obj->EndPoint();
+
+ if (
+ (in.GetSize() != 3) ||
+ (! in.GetValue(in[0], value[0])) ||
+ (! in.GetValue(in[1], value[1])) ||
+ (! in.GetValue(in[2], value[2]))
+ )
+ {
+ return false;
+ }
+ return true;
+}
+
+void
+CLASS(Line)::DefineClass()
+{
+ DEFINE_BASECLASS(SoccerNode);
+ DEFINE_FUNCTION(setBeginPoint);
+ DEFINE_FUNCTION(setEndPoint);
+}
Modified: trunk/rcssserver3d/plugin/soccer/restrictedvisionperceptor/restrictedvisionperceptor.cpp
===================================================================
--- trunk/rcssserver3d/plugin/soccer/restrictedvisionperceptor/restrictedvisionperceptor.cpp 2010-03-28 08:27:22 UTC (rev 189)
+++ trunk/rcssserver3d/plugin/soccer/restrictedvisionperceptor/restrictedvisionperceptor.cpp 2010-03-30 11:33:03 UTC (rev 190)
@@ -25,6 +25,12 @@
#include <oxygen/sceneserver/transform.h>
#include <soccerbase/soccerbase.h>
#include <salt/gmath.h>
+#include <list>
+#include <X11/X.h>
+#include <math.h>
+#include <salt/linesegment2.h>
+#include <limits>
+#include <iostream>
using namespace zeitgeist;
using namespace oxygen;
@@ -34,7 +40,8 @@
RestrictedVisionPerceptor::RestrictedVisionPerceptor() : Perceptor(),
mSenseMyPos(false),
mAddNoise(true),
- mStaticSenseAxis(true)
+ mStaticSenseAxis(true),
+ mSenseLine(false)
{
// set predicate name
SetPredicateName("See");
@@ -454,6 +461,11 @@
element.AddValue(sensedMyPos[2]);
}
+ if (mSenseLine)
+ {
+ SenseLine(predicate);
+ }
+
return true;
}
@@ -551,6 +563,11 @@
element.AddValue(sensedMyPos[2]);
}
+ if (mSenseLine)
+ {
+ SenseLine(predicate);
+ }
+
return true;
}
@@ -616,3 +633,233 @@
{
mSenseMyPos = sense;
}
+
+bool RestrictedVisionPerceptor::checkVisuable(RestrictedVisionPerceptor::ObjectData& od) const
+{
+ // theta is the angle in horizontal plane, with fwAngle as 0 degree
+ od.mTheta = gNormalizeDeg(gRadToDeg(gNormalizeRad(
+ gArcTan2(od.mRelPos[1], od.mRelPos[0])
+ )) - 90);
+
+ // latitude with fwPhi as 0 degreee
+ od.mPhi = gRadToDeg(gNormalizeRad(
+ gArcTan2(od.mRelPos[2],
+ Vector2f(od.mRelPos[0], od.mRelPos[1]).Length()
+ )
+ )
+ );
+
+ od.mDist = od.mRelPos.Length();
+ if (od.mDist <= 0.1)
+ {
+ // object is too close
+ return false;
+ }
+
+ const int hAngle_2 = mHViewCone >> 1;
+ if (gAbs(od.mTheta) > hAngle_2)
+ {
+ // object is out of view range
+ return false;
+ }
+
+ const int vAngle_2 = mVViewCone >> 1;
+ if (gAbs(od.mPhi) > vAngle_2)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+void RestrictedVisionPerceptor::SenseLine(Predicate& predicate)
+{
+ const float focalLength = 0.1f;
+ TLineList visibleLines;
+ SetupLines(visibleLines);
+
+ // TODO: precalculate it
+ // visual range
+ Vector2f ru(tan(gDegToRad<double>(mHViewCone*0.5))*focalLength, tan(gDegToRad<double>(mVViewCone*0.5))*focalLength);
+ Vector2f rb(ru.x(), -ru.y());
+ Vector2f lu(-ru.x(), ru.y());
+ Vector2f lb(-ru.x(), -ru.y());
+ LineSegment2f viewRangeLine[4];
+ viewRangeLine[0] = LineSegment2f(lu, ru);
+ viewRangeLine[1] = LineSegment2f(lb, rb);
+ viewRangeLine[2] = LineSegment2f(lu, lb);
+ viewRangeLine[3] = LineSegment2f(ru, rb);
+
+ for (TLineList::iterator i = visibleLines.begin(); i != visibleLines.end(); )
+ {
+ LineData& ld = (*i);
+
+ bool seeBeginPoint = checkVisuable(ld.mBeginPoint);
+ bool seeEndPoint = checkVisuable(ld.mEndPoint);
+
+ if (!(seeBeginPoint && seeEndPoint))
+ {
+ Vector3f bp3 = ld.mBeginPoint.mRelPos;
+ Vector3f ep3 = ld.mEndPoint.mRelPos;
+
+ if ( bp3.y() < focalLength && ep3.y() >= focalLength )
+ {
+ float t = ( focalLength - ep3.y() ) / ( bp3.y() - ep3.y() );
+ bp3 = ep3 + ( bp3 - ep3 ) * t;
+ }
+ else if ( ep3.y() < focalLength && bp3.y() >= focalLength )
+ {
+ float t = ( focalLength - bp3.y() ) / ( ep3.y() - bp3.y() );
+ ep3 = bp3 + ( ep3 - bp3 ) * t;
+ }
+
+ if ( bp3.y() > 0 && ep3.y() > 0 )
+ {
+ Vector2f bp = Vector2f(bp3.x(), bp3.z()) * focalLength / bp3.y();
+ Vector2f ep = Vector2f(ep3.x(), ep3.z()) * focalLength / ep3.y();
+ LineSegment2f l(bp, ep);
+
+ float CB = bp3.Length();
+ float CE = ep3.Length();
+ float BE = (bp3 - ep3).Length();
+ float CEB = acos((BE * BE + CE * CE - CB * CB) / (2 * BE * CE));
+ Vector3f Ef(ep.x(), focalLength, ep.y());
+ float CEf = Ef.Length();
+
+ Vector3f X[2];
+ int inum = 0;
+ for ( int i=0; i<4 && inum < 2; i++)
+ {
+ Vector2f ip;
+ if ( l.Intersection(viewRangeLine[i], ip) )
+ {
+ Vector3f Xf(ip.x(), focalLength, ip.y());
+ float CXf = Xf.Length();
+ float XfEf = (Xf - Ef).Length();
+ float XfCEf = acos((CXf * CXf + CEf * CEf - XfEf * XfEf) / (2 * CXf * CEf));
+ float CXE = gPI - CEB - XfCEf;
+ float EX = CE / sin(CXE) * sin(XfCEf);
+ X[inum] = ep3 + (bp3 - ep3) * (EX / BE);
+ inum++;
+ }
+ }
+
+ if ( inum == 2 )
+ {
+ ld.mBeginPoint.mRelPos = X[0];
+ checkVisuable(ld.mBeginPoint);
+ seeBeginPoint = true;
+
+ ld.mEndPoint.mRelPos = X[1];
+ checkVisuable(ld.mEndPoint);
+ seeEndPoint = true;
+ }
+ else if ( inum == 1 )
+ {
+ if ( !seeBeginPoint )
+ {
+ ld.mBeginPoint.mRelPos = X[0];
+ checkVisuable(ld.mBeginPoint);
+ seeBeginPoint = true;
+ }
+ else
+ {
+ ld.mEndPoint.mRelPos = X[0];
+ checkVisuable(ld.mEndPoint);
+ seeEndPoint = true;
+ }
+ }
+ }
+ }
+
+ if (seeBeginPoint && seeEndPoint)
+ {
+ // make some noise
+ ApplyNoise(ld.mBeginPoint);
+ ApplyNoise(ld.mEndPoint);
+
+ ++i;
+ }
+ else
+ {
+ i = visibleLines.erase(i);
+ }
+ }
+
+ // generate a sense entry
+ AddSense(predicate, visibleLines);
+}
+
+void
+RestrictedVisionPerceptor::SetupLines(TLineList& visibleLines)
+{
+ TLeafList lineList;
+ mActiveScene->GetChildrenOfClass("Line", lineList, true);
+
+ // determine position relative to the local reference frame
+ const Matrix& mat = mTransformParent->GetWorldTransform();
+
+ // get the transformation matrix describing the current orientation
+ Vector3f myPos = mat.Pos();
+ if (mAddNoise)
+ {
+ myPos -= mError;
+ }
+
+
+ for (TLeafList::iterator i = lineList.begin(); i != lineList.end(); ++i)
+ {
+ LineData ld;
+
+ ld.mLine = shared_static_cast<Line > (*i);
+
+ if (ld.mLine.get() == 0)
+ {
+ GetLog()->Error() << "Error: (RestrictedVisionPerceptor) skipped line: "
+ << (*i)->GetName() << "\n";
+ continue; // this should never happen
+ }
+
+ boost::shared_ptr<Transform> j = ld.mLine->GetTransformParent();
+
+ if (j.get() == 0)
+ {
+ GetLog()->Error() << "Error: (RestrictedVisionPerceptor) skipped line (2): "
+ << (*i)->GetName() << "\n";
+ continue; // this should never happen
+ }
+
+ const salt::Matrix& t = j->GetWorldTransform();
+ ld.mBeginPoint.mRelPos = mat.InverseRotate( t * ld.mLine->BeginPoint() - myPos );
+ ld.mEndPoint.mRelPos = mat.InverseRotate( t * ld.mLine->EndPoint() - myPos );
+
+ visibleLines.push_back(ld);
+ }
+}
+
+void RestrictedVisionPerceptor::AddSense(Predicate& predicate, const TLineList& lineList) const
+{
+ for (TLineList::const_iterator i = lineList.begin(); i != lineList.end(); ++i)
+ {
+ const LineData& ld = (*i);
+ ParameterList& element = predicate.parameter.AddList();
+ element.AddValue(std::string("L"));
+
+ ParameterList& begPos = element.AddList();
+ begPos.AddValue(std::string("pol"));
+ begPos.AddValue(ld.mBeginPoint.mDist);
+ begPos.AddValue(ld.mBeginPoint.mTheta);
+ begPos.AddValue(ld.mBeginPoint.mPhi);
+
+ ParameterList& endPos = element.AddList();
+ endPos.AddValue(std::string("pol"));
+ endPos.AddValue(ld.mEndPoint.mDist);
+ endPos.AddValue(ld.mEndPoint.mTheta);
+ endPos.AddValue(ld.mEndPoint.mPhi);
+ }
+}
+
+void RestrictedVisionPerceptor::SetSenseLine(bool sense)
+{
+ mSenseLine = sense;
+}
\ No newline at end of file
Modified: trunk/rcssserver3d/plugin/soccer/restrictedvisionperceptor/restrictedvisionperceptor.h
===================================================================
--- trunk/rcssserver3d/plugin/soccer/restrictedvisionperceptor/restrictedvisionperceptor.h 2010-03-28 08:27:22 UTC (rev 189)
+++ trunk/rcssserver3d/plugin/soccer/restrictedvisionperceptor/restrictedvisionperceptor.h 2010-03-30 11:33:03 UTC (rev 190)
@@ -29,6 +29,7 @@
#include <oxygen/sceneserver/transform.h>
#include <oxygen/agentaspect/agentaspect.h>
#include <agentstate/agentstate.h>
+#include "../line/line.h"
class RestrictedVisionPerceptor : public oxygen::Perceptor
{
@@ -67,6 +68,15 @@
typedef std::map<boost::shared_ptr<oxygen::BaseNode>, TObjectList> TNodeObjectsMap;
+ struct LineData
+ {
+ boost::shared_ptr<Line> mLine;
+ ObjectData mBeginPoint;
+ ObjectData mEndPoint;
+ };
+
+ typedef std::list<LineData> TLineList;
+
public:
RestrictedVisionPerceptor();
virtual ~RestrictedVisionPerceptor();
@@ -94,6 +104,9 @@
//! Turn sensing of agent position on/off
void SetSenseMyPos(bool sense);
+ // turn sensing of lines on/off
+ void SetSenseLine(bool sense);
+
/** Turn noise off/on.
\param add_noise flag if noise should be used at all.
*/
@@ -162,6 +175,13 @@
*/
bool DynamicAxisPercept(boost::shared_ptr<oxygen::PredicateList> predList);
+ /** Percept lines in the world */
+ void SenseLine(oxygen::Predicate& predicate);
+
+ void SetupLines(TLineList& visibleLines);
+
+ bool checkVisuable(ObjectData& od) const;
+
/** Checks if the given object is occluded, seen from from my_pos */
bool CheckOcclusion(const salt::Vector3f& my_pos, const ObjectData& od) const;
@@ -172,6 +192,9 @@
boost::shared_ptr<BaseNode> node,
TObjectList& objectList) const;
+ void AddSense(oxygen::Predicate& predicate,
+ const TLineList& lineList) const;
+
/** applies noise to the setup ObjectData */
void ApplyNoise(ObjectData& od) const;
@@ -201,6 +224,9 @@
*/
bool mStaticSenseAxis;
+ /** flag if the lines can be sensed */
+ bool mSenseLine;
+
//! horizontal opening of the vision cone
unsigned int mHViewCone;
//! vertical opening of the vision cone
Modified: trunk/rcssserver3d/plugin/soccer/restrictedvisionperceptor/restrictedvisionperceptor_c.cpp
===================================================================
--- trunk/rcssserver3d/plugin/soccer/restrictedvisionperceptor/restrictedvisionperceptor_c.cpp 2010-03-28 08:27:22 UTC (rev 189)
+++ trunk/rcssserver3d/plugin/soccer/restrictedvisionperceptor/restrictedvisionperceptor_c.cpp 2010-03-30 11:33:03 UTC (rev 190)
@@ -150,6 +150,22 @@
return true;
}
+FUNCTION(RestrictedVisionPerceptor,setSenseLine)
+{
+ bool inSenseLine;
+
+ if (
+ (in.GetSize() != 1) ||
+ (! in.GetValue(in.begin(),inSenseLine))
+ )
+ {
+ return false;
+ }
+
+ obj->SetSenseLine(inSenseLine);
+ return true;
+}
+
void CLASS(RestrictedVisionPerceptor)::DefineClass()
{
DEFINE_BASECLASS(oxygen/Perceptor);
@@ -160,4 +176,5 @@
DEFINE_FUNCTION(setViewCones);
DEFINE_FUNCTION(setPanRange);
DEFINE_FUNCTION(setTiltRange);
+ DEFINE_FUNCTION(setSenseLine);
}
Modified: trunk/spark/lib/salt/CMakeLists.txt
===================================================================
--- trunk/spark/lib/salt/CMakeLists.txt 2010-03-28 08:27:22 UTC (rev 189)
+++ trunk/spark/lib/salt/CMakeLists.txt 2010-03-30 11:33:03 UTC (rev 190)
@@ -15,6 +15,8 @@
sharedlibrary.h
vector.h
salt_defines.h
+ line2.h
+ linesegment2.h
)
set(salt_LIB_SRCS
Added: trunk/spark/lib/salt/line2.h
===================================================================
--- trunk/spark/lib/salt/line2.h (rev 0)
+++ trunk/spark/lib/salt/line2.h 2010-03-30 11:33:03 UTC (rev 190)
@@ -0,0 +1,305 @@
+/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*-
+
+ this file is part of rcssserver3D
+ Copyright (C) 2008,2009 SEU RoboCup Simulation Team, Southeast University , Nanjing, China.
+ Copyright (C) 2010 RoboCup Soccer Server 3D Maintenance Group
+ $Id$
+
+ 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; version 2 of the License.
+
+ 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _LINE2_H
+#define _LINE2_H
+
+#include <limits>
+#include "tvector.h"
+
+namespace salt {
+
+template <typename DATATYPE>
+class TLine2
+{
+ // a line is defined by the formula: ay + bx + c = 0
+ DATATYPE mA;
+ DATATYPE mB;
+ DATATYPE mC;
+public:
+
+ /**
+ * create line by given coefficients
+ *
+ * @param a the a coefficients
+ * @param b the b coefficients
+ * @param c the c coefficients
+ */
+ TLine2(DATATYPE a = 1, DATATYPE b = 0, DATATYPE c = -1)
+ : mA(a), mB(b), mC(c)
+ {
+ }
+
+ /**
+ * create line from tow points
+ *
+ * @param pos1 the one point
+ * @param pos2 the other point
+ */
+ template <typename P_T>
+ TLine2(const P_T &pos1,
+ const P_T &pos2)
+ {
+ // 1*y + bx + c = 0 => y = -bx - c
+ // with -b the direction coefficient (or slope)
+ // and c = - y - bx
+ DATATYPE dTemp = pos2[0] - pos1[0]; // determine the slope
+ if (fabs(dTemp) < std::numeric_limits<DATATYPE>::epsilon() ) {
+ // ay + bx + c = 0 with vertical slope=> a = 0, b = 1
+ mA = 0.0;
+ mB = 1.0;
+ } else {
+ // y = (-b)x -c with -b the slope of the line
+ mA = 1.0;
+ mB = -(pos2[1] - pos1[1]) / dTemp;
+ }
+ // ay + bx + c = 0 ==> c = -a*y - b*x
+ mC = -mA * pos2.y() - mB * pos2.x();
+ }
+
+ /**
+ * create line from one point and an angle
+ *
+ * @param pos the point in line
+ * @param angle the sclope angle
+ */
+ template <typename P_T>
+ TLine2(const P_T &pos, DATATYPE angle)
+ {
+ // calculate point somewhat further in direction 'angle'
+ // and make line from these two points.
+ P_T pos2 = pos;
+ pos2.x() += cosDeg(angle);
+ pos2.y() += sinDeg(angle);
+ *this = TLine2(pos, pos2);
+ }
+
+ DATATYPE a() const
+ {
+ return mA;
+ }
+
+ DATATYPE b() const
+ {
+ return mB;
+ }
+
+ DATATYPE c() const
+ {
+ return mC;
+ }
+
+ DATATYPE& a()
+ {
+ return mA;
+ }
+
+ DATATYPE& b()
+ {
+ return mB;
+ }
+
+ DATATYPE& c()
+ {
+ return mC;
+ }
+
+ /**
+ * calculate the intersection of two lines
+ *
+ * @param line the other line
+ *
+ * @return the intersection
+ */
+ template <typename P_T>
+ bool Intersection(const TLine2 &line, P_T &p) const
+ {
+ DATATYPE L = line.a() * mB - mA * line.b();
+ if (abs(L) < std::numeric_limits<DATATYPE>::epsilon()) {
+ // lines are parallel, no intersection
+ return false;
+ }
+ if (mA == 0) {
+ // bx + c = 0 and a2*y + b2*x + c2 = 0 ==> x = -c/b
+ // calculate x using the current line
+ p.x() = -mC / mB; // and calculate the y using the second line
+ p.y() = line.YGivenX(p.x());
+ } else if (line.a() == 0) {
+ // ay + bx + c = 0 and b2*x + c2 = 0 ==> x = -c2/b2
+ p.x() = -line.c() / line.b();
+ // calculate x using
+ p.y() = YGivenX(p.x());
+ // 2nd line and calculate y using current line
+ } else {
+ // ay + bx + c = 0 and a2y + b2*x + c2 = 0
+ // y = (-b2/a2)x - c2/a2
+ // bx = -a*y - c => bx = -a*(-b2/a2)x -a*(-c2/a2) - c
+ // ==> a2*bx = a*b2*x + a*c2 - a2*c
+ // ==> x = (a*c2 - a2*c)/(a2*b - a*b2)
+ p.x() = (mA * line.c() - line.a() * mC) / L;
+ p.y() = YGivenX(p.x());
+ }
+ return true;
+ }
+
+ /**
+ * ay + bx + c = 0 -> y = (-b/a)x + (-c/a)
+ * tangent: y = (a/b)*x + C1 -> by - ax + C2 = 0 => C2 = ax - by
+ * with pos.y = y, pos.x = x
+ *
+ * @param pos the tangent intersection
+ *
+ * @return the tangent line of this line
+ */
+ template<typename P_T>
+ TLine2 TangentLine(const P_T &pos) const
+ {
+ return TLine2(mB, -mA, mA * pos.x() - mB * pos.y());
+ }
+
+ /**
+ * calculate the closest point of a given point to this line
+ *
+ * @param pos the given point
+ *
+ * @return the closest point
+ */
+ template<typename P_T>
+ P_T PointOnLineClosestTo(const P_T &pos) const
+ {
+ TLine2 l2 = TangentLine(pos); // get tangent line
+ // and intersection between the two lines
+ return Intersection(l2);
+ }
+
+ /**
+ * calculate the distance from a given point to this line
+ *
+ * @param pos the given point
+ *
+ * @return the distance from the pos to this line
+ */
+ template<typename P_T>
+ DATATYPE DistanceToPoint(const P_T &pos) const
+ {
+ return (PointOnLineClosestTo(pos) - pos).length();
+ }
+
+ /**
+ * calculate the Y value by given X value
+ *
+ * @param x the given x coordinate value
+ *
+ * @return the Y coordinate value
+ */
+ DATATYPE YGivenX(DATATYPE x) const
+ {
+ if (mA == 0) {
+ std::cerr << __FILE__ << __LINE__ << __FUNCTION__
+ << " Cannot calculate Y coordinate: " << std::endl;
+ return 0;
+ }
+ // ay + bx + c = 0 ==> y = -(b*x + c)/a
+ return -(mB * x + mC) / mA;
+ }
+
+ /**
+ * calculate the X value by given Y value
+ *
+ * @param y the given Y coordinate value
+ *
+ * @return the X coordinate value
+ */
+ DATATYPE XGivenY(DATATYPE y) const
+ {
+ if (mB == 0) {
+ std::cerr << __FILE__ << __LINE__ << __FUNCTION__
+ << "Cannot calculate X coordinate\n" << std::endl;
+ return 0;
+ }
+ // ay + bx + c = 0 ==> x = -(a*y + c)/b
+ return -(mA * y + mC) / mB;
+ }
+
+ /**
+ * calculate the location of point to the line
+ *
+ * @param p the given point
+ *
+ * @return +1 means upper the line
+ * 0 means on the line
+ * -1 means lower the line
+ */
+ template <typename P_T>
+ int Location(const P_T & p)const
+ {
+ return sign(mA * p.y() + mB * p.x() + mC);
+ }
+
+ /**
+ * calculate the ang for line
+ */
+ DATATYPE GetAngle()
+ {
+ return atan2(-mB, mA);
+ }
+
+ /**
+ * @param[in] pos1 first point
+ * @param pos2 second point
+ * @return
+ */
+ template<typename P_T>
+ static TLine2 MidperpendicularFromTwoPoints(const P_T &pos1, const P_T &pos2)
+ {
+ TLine2 l1(pos1, pos2);
+ P_T posMid = (pos1 + pos2)*0.5;
+ return l1.TangentLine(posMid);
+ }
+
+};
+
+/// dump
+
+template<typename DATATYPE>
+std::ostream & operator <<(std::ostream & os, TLine2<DATATYPE> l)
+{
+ DATATYPE a = l.a();
+ DATATYPE b = l.b();
+ DATATYPE c = l.c();
+ // ay + bx + c = 0 -> y = -b/a x - c/a
+ if (a == 0) {
+ os << "x = " << -c / b;
+ } else {
+ os << "y = ";
+ if (b != 0)
+ os << -b / a << "x ";
+ if (c > 0)
+ os << "- " << fabs(c / a);
+ else if (c < 0)
+ os << "+ " << fabs(c / a);
+ }
+ return os;
+}
+
+} // namespace salt
+#endif /* _LINE2_H */
+
Added: trunk/spark/lib/salt/linesegment2.h
===================================================================
--- trunk/spark/lib/salt/linesegment2.h (rev 0)
+++ trunk/spark/lib/salt/linesegment2.h 2010-03-30 11:33:03 UTC (rev 190)
@@ -0,0 +1,129 @@
+/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*-
+
+ this file is part of rcssserver3D
+ Copyright (C) 2008,2009 SEU RoboCup Simulation Team, Southeast University , Nanjing, China.
+ Copyright (C) 2010 RoboCup Soccer Server 3D Maintenance Group
+ $Id$
+
+ 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; version 2 of the License.
+
+ 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _LINESEGMENT2_H
+#define _LINESEGMENT2_H
+
+#include "line2.h"
+
+namespace salt {
+
+template <typename DATATYPE, typename P_T>
+class TLineSegment2 : public TLine2<DATATYPE>
+{
+ /// endpoints
+ P_T mP[2];
+public:
+
+ TLineSegment2()
+ {
+ }
+
+ TLineSegment2(const P_T & p0, const P_T & p1)
+ : TLine2<DATATYPE>(p0, p1)
+ {
+ mP[0] = p0;
+ mP[1] = p1;
+ }
+
+ const P_T & p0() const
+ {
+ return mP[0];
+ }
+
+ const P_T & p1() const
+ {
+ return mP[1];
+ }
+
+ bool IsBetween(const P_T & p) const
+ {
+ return p[0] <= std::max(mP[0][0], mP[1][0])
+ && p[0] >= std::min(mP[0][0], mP[1][0])
+ && p[1] <= std::max(mP[0][1], mP[1][1])
+ && p[1] >= std::min(mP[0][1], mP[1][1]);
+ }
+
+ DATATYPE Length() const
+ {
+ return ( mP[0] - mP[1]).Length();
+ }
+
+ bool IsContain(const P_T & p) const
+ {
+ return (p - mP[0]).Length() + (p - mP[1]).Length()
+ < Length() + std::numeric_limits<DATATYPE>::epsilon();
+ }
+
+ /**
+ * calculate the intersection of the segment and a given line
+ *
+ * @param line the given line
+ * @param intersection retrun the intersection
+ *
+ * @return if the segment and line have intersection
+ */
+ bool IntersectionWithLine(const TLine2<DATATYPE>& line,
+ P_T & intersection)const
+ {
+ if ( TLine2<DATATYPE>::Intersection(line, intersection) )
+ {
+ return IsBetween(intersection);
+ }
+ return false;
+ }
+
+ /**
+ * calculate the interseciton of two segment
+ *
+ * @param seg2 the other segment
+ * @param intersection return the intersection
+ *
+ * @return if the tow segments have intersection
+ */
+ bool Intersection(const TLineSegment2& seg2,
+ P_T & intersection)const
+ {
+ if (IntersectionWithLine(seg2, intersection)) {
+ return seg2.IsBetween(intersection);
+ }
+ return false;
+ }
+
+ /**
+ * if there is an intersection of two segment
+ *
+ * @param seg2 the other segment
+ *
+ * @return if the tow segments have intersection
+ */
+ bool IsIntersect(const TLineSegment2& seg2) const
+ {
+ P_T intersection;
+ return Intersection(seg2, intersection);
+ }
+};
+
+typedef TLineSegment2<float, Vector2f> LineSegment2f;
+
+} // namespace salt
+#endif /* _LINESEGMENT2_H */
+
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|