[openrtm-commit:01563] r2631 - trunk/OpenRTM-aist/src/lib/rtm

openrtm @ openrtm.org openrtm @ openrtm.org
2015年 6月 17日 (水) 21:43:35 JST


Author: n-ando
Date: 2015-06-17 21:43:35 +0900 (Wed, 17 Jun 2015)
New Revision: 2631

Modified:
   trunk/OpenRTM-aist/src/lib/rtm/InPort.h
   trunk/OpenRTM-aist/src/lib/rtm/OutPortBase.cpp
   trunk/OpenRTM-aist/src/lib/rtm/OutPortBase.h
   trunk/OpenRTM-aist/src/lib/rtm/OutPortConnector.cpp
   trunk/OpenRTM-aist/src/lib/rtm/OutPortConnector.h
Log:
[incompat,function] Direct data put functionality between data ports has been implemented. refs #3224

Modified: trunk/OpenRTM-aist/src/lib/rtm/InPort.h
===================================================================
--- trunk/OpenRTM-aist/src/lib/rtm/InPort.h	2015-06-17 07:35:58 UTC (rev 2630)
+++ trunk/OpenRTM-aist/src/lib/rtm/InPort.h	2015-06-17 12:43:35 UTC (rev 2631)
@@ -27,6 +27,8 @@
 #include <coil/TimeValue.h>
 #include <coil/Time.h>
 #include <coil/OS.h>
+#include <coil/Mutex.h>
+#include <coil/Guard.h>
 
 #include <rtm/RTC.h>
 #include <rtm/Typename.h>
@@ -152,8 +154,8 @@
       :	InPortBase(name, ::CORBA_Util::toRepositoryId<DataType>()),
 #endif
         m_name(name), m_value(value),
-	m_OnRead(NULL),  m_OnReadConvert(NULL),
-	m_status(1)
+        m_OnRead(NULL),  m_OnReadConvert(NULL),
+        m_status(1), m_directNewData(false)
     {
     }
     
@@ -230,6 +232,14 @@
       // In single-buffer mode, all connectors share the same buffer. This
       // means that we only need to read from the first connector to get data
       // received by any connector.
+      {
+        Guard gurad(m_valueMutex);
+        if (m_directNewData == true)
+          {
+            RTC_DEBUG(("isNew() returns true because of direct write."));
+            return true;
+          }
+      }
       int r(0);
       {
         Guard guard(m_connectorsMutex);
@@ -277,6 +287,7 @@
     virtual bool isEmpty()
     {
       RTC_TRACE(("isEmpty()"));
+      if (m_directNewData == true) { return false; }
       int r(0);
 
       {
@@ -302,6 +313,13 @@
       return false;
     }
 
+    virtual void write(const DataType& data)
+    {
+      Guard guard(m_valueMutex);
+      m_value = data;
+      m_directNewData = true;
+    }
+
     /*!
      * @if jp
      *
@@ -385,7 +403,23 @@
           (*m_OnRead)();
           RTC_TRACE(("OnRead called"));
         }
-
+      // 1) direct connection
+      {
+        Guard guard(m_valueMutex);
+        if (m_directNewData == true)
+          {
+            RTC_DEBUG(("Direct data transfer"));
+            if (m_OnReadConvert != 0) 
+              {
+                m_value = (*m_OnReadConvert)(m_value);
+                RTC_DEBUG(("OnReadConvert for direct data called"));
+                return true;
+              }
+            m_directNewData = false;
+            return true;
+          }
+      }
+      // 2) network connection
       cdrMemoryStream cdr;
       ReturnCode ret;
       {
@@ -395,15 +429,16 @@
             RTC_DEBUG(("no connectors"));
             return false;
           }
-        
+
         // In single-buffer mode, all connectors share the same buffer. This
         // means that we only need to read from the first connector to get data
         // received by any connector.
         ret = m_connectors[0]->read(cdr);
-	m_status[0] = ret;
+        m_status[0] = ret;
       }
       if (ret == PORT_OK)
         {
+          Guard guard(m_valueMutex);
           RTC_DEBUG(("data read succeeded"));
           m_value <<= cdr;
           if (m_OnReadConvert != 0) 
@@ -627,6 +662,7 @@
      * @endif
      */
     DataType& m_value;
+    mutable coil::Mutex m_valueMutex;
     
     /*!
      * @if jp
@@ -646,7 +682,23 @@
      */
     OnReadConvert<DataType>* m_OnReadConvert;
 
+    /*!
+     * @if jp
+     * @brief コネクタごとのリードステータス
+     * @else
+     * @brief Read status of each connector
+     * @endif
+     */
     DataPortStatusList m_status;
+
+    /*!
+     * @if jp
+     * @brief ダイレクトデータ転送フラグ
+     * @else
+     * @brief A flag for direct data transfer
+     * @endif
+     */
+    bool m_directNewData;
   };
 }; // End of namesepace RTM
 

Modified: trunk/OpenRTM-aist/src/lib/rtm/OutPortBase.cpp
===================================================================
--- trunk/OpenRTM-aist/src/lib/rtm/OutPortBase.cpp	2015-06-17 07:35:58 UTC (rev 2630)
+++ trunk/OpenRTM-aist/src/lib/rtm/OutPortBase.cpp	2015-06-17 12:43:35 UTC (rev 2631)
@@ -29,7 +29,6 @@
 #include <rtm/OutPortBase.h>
 #include <rtm/PublisherBase.h>
 
-
 namespace RTC
 {
   /*!
@@ -971,6 +970,19 @@
 
         // endian type set
         connector->setEndian(m_littleEndian);
+
+        // set direct InPort if ConnectorProfile
+        //  .properties["dataport.outport.direct_dataput.disable"] != YES
+        if (!coil::toBool(prop["direct_dataput.disable"], "YES", "NO", false))
+          {
+            InPortBase* inport = getLocalInPort(profile);
+            if (inport != NULL)
+              {
+                connector->setInPort(inport);
+              }
+          }
+        // end of direct port
+
         m_connectors.push_back(connector);
         RTC_PARANOID(("connector pushback done: size = %d",
                       m_connectors.size()));
@@ -1036,4 +1048,41 @@
     return 0;
   }
 
+  /*!
+   * @if jp
+   * @brief ローカルのピアInPortを取得
+   * @else
+   * @brief Getting local peer InPort if available
+   * @endif
+   */
+  InPortBase*
+  OutPortBase::getLocalInPort(const ConnectorInfo& profile)
+  {
+    RTC_DEBUG(("Trying direct port connection."));
+    CORBA::ORB_var orb = RTC::Manager::instance().getORB();
+    RTC_DEBUG(("Current connector profile: name=%s, id=%s",
+               profile.name.c_str(), profile.id.c_str()));
+    // finding peer port object
+    for (size_t i = 0;  i < profile.ports.size() ; ++i)
+      {
+        CORBA::Object_var obj;
+        obj = orb->string_to_object(profile.ports[i].c_str());
+        if (getPortRef()->_is_equivalent(obj)) { continue; }
+        RTC_DEBUG(("Peer port found: %s.", profile.ports[i].c_str()));
+        try
+          {
+            PortableServer::POA_var poa = RTC::Manager::instance().getPOA();
+            InPortBase* inport = dynamic_cast<InPortBase*>
+              (poa->reference_to_servant(obj));
+            RTC_DEBUG(("InPortBase servant pointer is obtained."));
+            return inport;
+          }
+        catch (...)
+          {
+            RTC_DEBUG(("Peer port is remote port"));
+          }
+      }
+    return NULL;
+  }
+
 }; // end of namespace RTM

Modified: trunk/OpenRTM-aist/src/lib/rtm/OutPortBase.h
===================================================================
--- trunk/OpenRTM-aist/src/lib/rtm/OutPortBase.h	2015-06-17 07:35:58 UTC (rev 2630)
+++ trunk/OpenRTM-aist/src/lib/rtm/OutPortBase.h	2015-06-17 12:43:35 UTC (rev 2631)
@@ -1016,6 +1016,15 @@
   protected:
     /*!
      * @if jp
+     * @brief ローカルのピアInPortを取得
+     * @else
+     * @brief Getting local peer InPort if available
+     * @endif
+     */
+    InPortBase* getLocalInPort(const ConnectorInfo& profile);
+    
+    /*!
+     * @if jp
      * @brief プロパティ
      * @else
      * @brief Properties

Modified: trunk/OpenRTM-aist/src/lib/rtm/OutPortConnector.cpp
===================================================================
--- trunk/OpenRTM-aist/src/lib/rtm/OutPortConnector.cpp	2015-06-17 07:35:58 UTC (rev 2630)
+++ trunk/OpenRTM-aist/src/lib/rtm/OutPortConnector.cpp	2015-06-17 12:43:35 UTC (rev 2631)
@@ -29,7 +29,8 @@
    * @endif
    */
   OutPortConnector::OutPortConnector(ConnectorInfo& info)
-    : rtclog("OutPortConnector"), m_profile(info), m_littleEndian(true)
+    : rtclog("OutPortConnector"), m_profile(info), m_littleEndian(true),
+      m_directInPort(NULL)
   {
   }
 

Modified: trunk/OpenRTM-aist/src/lib/rtm/OutPortConnector.h
===================================================================
--- trunk/OpenRTM-aist/src/lib/rtm/OutPortConnector.h	2015-06-17 07:35:58 UTC (rev 2630)
+++ trunk/OpenRTM-aist/src/lib/rtm/OutPortConnector.h	2015-06-17 12:43:35 UTC (rev 2631)
@@ -22,7 +22,10 @@
 
 #include <rtm/SystemLogger.h>
 #include <rtm/ConnectorBase.h>
+#include <rtm/InPortBase.h>
+#include <rtm/InPort.h>
 
+
 namespace RTC
 {
   /*!
@@ -208,13 +211,27 @@
     template <class DataType>
     ReturnCode write(const DataType& data)
     {
+      if (m_directInPort != NULL)
+        {
+          static_cast<InPort<DataType>*>(m_directInPort)->write(data);
+          return PORT_OK;
+        }
       m_cdr.rewindPtrs();
       RTC_TRACE(("connector endian: %s", isLittleEndian() ? "little":"big"));
       m_cdr.setByteSwapFlag(isLittleEndian());
       data >>= m_cdr;
       return write(m_cdr);
     }
-
+    
+    bool setInPort(InPortBase* directInPort)
+    {
+      if (directInPort == NULL)
+        {
+          return false;
+        }
+      m_directInPort = directInPort;
+      return true;
+    }
   protected:
     /*!
      * @if jp
@@ -249,6 +266,15 @@
      */
     cdrMemoryStream m_cdr;
 
+    /*!
+     * @if jp
+     * @brief 同一プロセス上のピアInPortのポインタ
+     * @else
+     * @brief InProt pointer to the peer in the same process
+     * @endif
+     */
+    InPortBase* m_directInPort;
+
   };
 }; // namespace RTC
 



More information about the openrtm-commit mailing list