예제 #1
0
bool DataPool::Connection::addPort(RTT::base::PortInterface *port) {
  RTT::base::InputPortInterface *inputPort   = dynamic_cast<RTT::base::InputPortInterface *>(port);
  RTT::base::OutputPortInterface *outputPort = dynamic_cast<RTT::base::OutputPortInterface *>(port);

  if (inputPort) {
    if (readers.count(inputPort)) {
      RTT::log(RTT::Error) << "InputPort " << inputPort->getName() << " is already a member of this connection" << RTT::endlog();
      return false;
    }
    readers.insert(inputPort);
    this->internalOutputPort->connectTo(inputPort);
    for(std::set<RTT::base::OutputPortInterface *>::iterator it = writers.begin(); it != writers.end(); ++it) (*it)->connectTo(inputPort);
    return true;
  }

  if (outputPort) {
    if (writers.count(outputPort)) {
      RTT::log(RTT::Error) << "OutputPort " << outputPort->getName() << " is already a member of this connection" << RTT::endlog();
      return false;
    }
    writers.insert(outputPort);
    outputPort->connectTo(this->internalInputPort);
    for(std::set<RTT::base::InputPortInterface *>::iterator it = readers.begin(); it != readers.end(); ++it) outputPort->connectTo(*it);
    return true;
  }

  return false;
}
예제 #2
0
// report a specific connection.
bool Logger::reportPort(const std::string& component, const std::string& port ) {
    TaskContext* comp = this->getPeer(component);
    if ( !comp )
    {
        log(Error) << "no such component " << component << endlog();
        return false;
    }

    RTT::base::OutputPortInterface* writer = dynamic_cast<RTT::base::OutputPortInterface*>(comp->ports()->getPort(port));
    if ( !writer )
    {
        log(Error) << "component " << component << " does not have a port named " << port << ", or it is a read port" << endlog();
        return false;
    }

    
    std::string portname(component + "." + port);
    RTT::base::PortInterface *pi = ports()->getPort(portname);
    
    if(pi) // we are already reporting this port
    {
        log(Info) << "port " << port << " of component " << component << " is already logged" << endlog();
        return true;
    }

    // Create the corresponding read port
    RTT::base::InputPortInterface* reader = static_cast<RTT::base::InputPortInterface*>(writer->antiClone());
    reader->setName(portname);
    writer->createBufferConnection(*reader, 25);

    return addLoggingPort(reader, portname);
}
예제 #3
0
void DataPool::Connection::removePort(RTT::base::PortInterface *port) {
  RTT::base::InputPortInterface *inputPort   = dynamic_cast<RTT::base::InputPortInterface *>(port);
  RTT::base::OutputPortInterface *outputPort = dynamic_cast<RTT::base::OutputPortInterface *>(port);

  if (inputPort) {
    this->internalOutputPort->disconnect(inputPort);
    inputPort->disconnect();
    readers.erase(inputPort);
  }

  if (outputPort) {
    this->internalInputPort->disconnect(outputPort);
    outputPort->disconnect();
    writers.erase(outputPort);
  }
}
예제 #4
0
 RTT::InputPort<T> &getReader(RTT::ConnPolicy const& policy)
 {
     if(!reader)
     {
         reader = dynamic_cast<RTT::InputPort<T> *>(port->antiClone());
         RTT::TaskContext *clientTask = getClientTask();
         clientTask->addPort(*reader);
         reader->connectTo(port, policy);
     }
     
     return *reader;
 };    
예제 #5
0
 ~OutputProxyPort()
 {
     deleteReader();
     port->disconnect();
 }
예제 #6
0
 bool connectTo(InputProxyPort<T> &inputPort)
 {
     return port->connectTo(inputPort.port);
 };
예제 #7
0
RTT::base::ChannelElementBase::shared_ptr RemoteInputPort::buildRemoteChannelOutput(
        RTT::base::OutputPortInterface& output_port,
        RTT::types::TypeInfo const* type,
        RTT::base::InputPortInterface& reader_,
        RTT::ConnPolicy const& policy)
{
    // This is called by the createConnection()->createRemoteConnection() code of the ConnFactory.
    Logger::In in("RemoteInputPort::buildRemoteChannelOutput");

    // First we delegate this call to the remote side, which will create a corba channel element,
    // buffers and channel output and attach this to the real input port.
    CRemoteChannelElement_var remote;
    RTT::base::ChannelElementBase::shared_ptr buf;
    try {
        CConnPolicy cpolicy = toCORBA(policy);
        CChannelElement_var ret = dataflow->buildChannelOutput(getName().c_str(), cpolicy);
        if ( CORBA::is_nil(ret) ) {
            return 0;
        }
        remote = CRemoteChannelElement::_narrow( ret.in() );
        policy.name_id = toRTT(cpolicy).name_id;
    }
    catch(CORBA::Exception& e)
    {
        log(Error) << "Caught CORBA exception while creating a remote channel output:" << endlog();
        log(Error) << CORBA_EXCEPTION_INFO( e ) <<endlog();
        return NULL;
    }

    // Input side is now ok and waiting for us to complete. We build our corba channel element too
    // and connect it to the remote side and vice versa.
    CRemoteChannelElement_i*  local =
        static_cast<CorbaTypeTransporter*>(type->getProtocol(ORO_CORBA_PROTOCOL_ID))
                            ->createChannelElement_i(output_port.getInterface(), mpoa, policy.pull);

    CRemoteChannelElement_var proxy = local->_this();
    local->setRemoteSide(remote);
    remote->setRemoteSide(proxy.in());
    local->_remove_ref();

    RTT::base::ChannelElementBase::shared_ptr corba_ceb = dynamic_cast<RTT::base::ChannelElementBase*>(local);

    // Note: this probably needs to factored out, see also DataFlowI.cpp:buildChannelOutput() for the counterpart of this code.
    // If the user specified OOB, we prepend the prefered transport.
    // This inserts a channel element before our corba channel element.
    // The remote input side will have done this too in the above step.
    if ( policy.transport != 0 && policy.transport != ORO_CORBA_PROTOCOL_ID ) {
        // create alternative path / out of band transport.
        string name =  policy.name_id ;
        if ( type->getProtocol(policy.transport) == 0 ) {
            log(Error) << "Could not create out-of-band transport for port "<< name << " with transport id " << policy.transport <<endlog();
            log(Error) << "No such transport registered. Check your policy.transport settings or add the transport for type "<< type->getTypeName() <<endlog();
        }
        RTT::base::ChannelElementBase* ceb = type->getProtocol(policy.transport)->createStream(this, policy, true);
        if (ceb) {
            // insertion before corba.
            ceb->setOutput( corba_ceb );
            corba_ceb = ceb;
            log(Info) <<"Redirecting data for port "<<name << " to out-of-band protocol "<< policy.transport << endlog();
        } else {
            log(Error) << "The type transporter for type "<<type->getTypeName()<< " failed to create a dual channel for port " << name<<endlog();
        }
    } else {
        // if no oob present, create a buffer at output port to guarantee RT delivery of data. (is always present in push&pull).
        buf = type->buildDataStorage(policy);
        assert(buf);
        buf->setOutput( corba_ceb );
        corba_ceb = buf;
    }
    // store the object reference in a map, for future lookup in channelReady().
    // this is coupled with the use of channelReady(). We assume the caller will always pass
    // chan->getOutputEndPoint() in that function.
    channel_map[ corba_ceb->getOutputEndPoint().get() ] = CChannelElement::_duplicate( remote );
    // The ChannelElementBase object that represents reader_half on this side
    return corba_ceb;
}