All Downloads are FREE. Search and download functionalities are using the official Maven repository.

us.ihmc.pubsub.impl.fastRTPS.FastRTPSDomain Maven / Gradle / Ivy

There is a newer version: 1.0.0
Show newest version
/**
 * Copyright 2024 Florida Institute for Human and Machine Cognition (IHMC) Licensed under the Apache
 * License, Version 2.0 (the "License"); you may not use this file except in compliance with the
 * License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */
package us.ihmc.pubsub.impl.fastRTPS;

import com.eprosima.xmlschemas.fastrtps_profiles.Dds;
import com.eprosima.xmlschemas.fastrtps_profiles.ProfilesType;
import org.apache.commons.lang3.SystemUtils;
import us.ihmc.commons.thread.ThreadTools;
import us.ihmc.pubsub.Domain;
import us.ihmc.pubsub.TopicDataType;
import us.ihmc.pubsub.attributes.ParticipantProfile;
import us.ihmc.pubsub.attributes.PublisherAttributes;
import us.ihmc.pubsub.attributes.SubscriberAttributes;
import us.ihmc.pubsub.common.LogLevel;
import us.ihmc.pubsub.participant.Participant;
import us.ihmc.pubsub.participant.ParticipantListener;
import us.ihmc.pubsub.publisher.Publisher;
import us.ihmc.pubsub.publisher.PublisherListener;
import us.ihmc.pubsub.subscriber.Subscriber;
import us.ihmc.pubsub.subscriber.SubscriberListener;
import us.ihmc.rtps.impl.fastRTPS.FastRTPSJNI;
import us.ihmc.tools.nativelibraries.NativeLibraryLoader;

import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.JAXBException;
import jakarta.xml.bind.Marshaller;
import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;

public class FastRTPSDomain implements Domain
{
   public static final String FAST_DDS_DISCOVERY_CONFIGURABLE_PREFIX = "44.53.%02X.5f.45.50.52.4f.53.49.4d.41";
   public static final String FAST_DDS_XML_NAMESPACE = "http://www.eprosima.com/XMLSchemas/fastRTPS_Profiles";
   public static final String FAST_DDS_METATRAFFIC_UNICAST_LOCATOR_LIST = "metatrafficUnicastLocatorList";
   public static final String FAST_DDS_TRANSPORT = "transport_descriptors";
   public static final String FAST_DDS_PARTICIPANT = "participant";
   public static final String FAST_DDS_PUBLISHER = "publisher";
   public static final String FAST_DDS_SUBSCRIBER = "subscriber";
   public static final String FAST_DDS_NANOSEC = "nanosec";
   public static final String FAST_DDS_SEC = "sec";
   public static final int DEFAULT_DISCOVERY_SERVER_PORT = 11811;

   private final ArrayList participants = new ArrayList<>();
   private final ArrayList allParticipantsForStatistics = new ArrayList<>();

   private static boolean useSystemFastRTPS = false;
   private static FastRTPSDomain instance = null;

   /** This method will create the instance if it does not exist. */
   public static synchronized FastRTPSDomain getInstance(boolean useSystemFastRTPS)
   {
      if (instance == null)
      {
         FastRTPSDomain.useSystemFastRTPS = useSystemFastRTPS;
         instance = new FastRTPSDomain(useSystemFastRTPS);
      }

      if (FastRTPSDomain.useSystemFastRTPS != useSystemFastRTPS)
      {
         if (useSystemFastRTPS)
         {
            throw new RuntimeException("Loading FastRTPS using the system FastRTPS library, but the builtin FastRTPS library is already loaded.");
         }
         else
         {
            throw new RuntimeException("Loading FastRTPS using the builtin FastRTPS library, but the system FastRTPS library is already loaded.");
         }
      }

      return instance;
   }

   /** @return The instance if {@link #getInstance} has been called, else null. */
   public static synchronized Domain accessInstance()
   {
      return instance;
   }

   private FastRTPSDomain(boolean useSystemFastRTPS)
   {
      try
      {
         if (useSystemFastRTPS)
         {
            System.loadLibrary("FastRTPSWrapper");
         }
         else
         {
            NativeLibraryLoader.loadLibrary(new FastRTPSNativeLibrary());

            // Force initialization of the FastRTPS class by setting the log level. This allows early bailout if there are linking errors.
            FastRTPSJNI.LogLevel_setLogLevel(0);
         }
      }
      catch (UnsatisfiedLinkError e)
      {
         if (SystemUtils.IS_OS_WINDOWS)
         {
            throw new UnsatisfiedLinkError("Cannot load library, make sure to install Microsoft Visual C++ 2022 Redistributable (x64) (https://aka.ms/vs/17/release/vc_redist.x64.exe). "
                  + e.getMessage());
         }
         else
         {
            throw e;
         }
      }
   }

   @Override
   public synchronized Participant createParticipant(ParticipantProfile att, ParticipantListener participantListener) throws IOException
   {
      FastRTPSParticipant participant = new FastRTPSParticipant(att, participantListener);
      participants.add(participant);
      synchronized (allParticipantsForStatistics)
      {
         allParticipantsForStatistics.add(participant);
      }
      return participant;
   }

   @Override
   public synchronized Publisher createPublisherImpl(Participant participant, PublisherAttributes att, PublisherListener listener)
         throws IOException, IllegalArgumentException
   {
      Publisher publisher = null;

      for (FastRTPSParticipant fastRTPSParticipant : participants)
      {
         if (fastRTPSParticipant == participant)
         {
            publisher = fastRTPSParticipant.createPublisher(att, listener);
            break;
         }
      }

      if (publisher == null)
      {
         throw new IllegalArgumentException("Participant is not part of this domain.");
      }

      ThreadTools.sleep(1);

      return publisher;
   }

   @Override
   public synchronized Subscriber createSubscriberImpl(Participant participant, SubscriberAttributes attrs, SubscriberListener listener)
         throws IOException, IllegalArgumentException
   {

      Subscriber subscriber = null;

      for (FastRTPSParticipant fastRTPSParticipant : participants)
      {
         if (fastRTPSParticipant == participant)
         {
            subscriber = fastRTPSParticipant.createSubscriber(attrs, listener);
            break;
         }
      }

      if (subscriber == null)
      {
         throw new IllegalArgumentException("Participant is not part of this domain.");
      }

      ThreadTools.sleep(1);

      return subscriber;
   }

   @Override
   public synchronized boolean removeParticipant(Participant participant)
   {
      for (int i = 0; i < participants.size(); i++)
      {
         if (participants.get(i) == participant)
         {
            participants.get(i).delete();
            participants.remove(i);
            return true;
         }
      }

      return false;
   }

   @Override
   public synchronized boolean removePublisher(Publisher publisher)
   {
      for (int i = 0; i < participants.size(); i++)
      {
         if (participants.get(i).getGuid().getGuidPrefix().equals(publisher.getGuid().getGuidPrefix()))
         {
            return participants.get(i).removePublisher(publisher);
         }
      }
      return false;
   }

   @Override
   public synchronized boolean removeSubscriber(Subscriber subscriber)
   {
      for (int i = 0; i < participants.size(); i++)
      {
         if (participants.get(i).getGuid().getGuidPrefix().equals(subscriber.getGuid().getGuidPrefix()))
         {
            return participants.get(i).removeSubscriber(subscriber);
         }
      }
      return false;
   }

   @Override
   public synchronized TopicDataType getRegisteredType(Participant participant, String typeName)
   {
      for (int i = 0; i < participants.size(); i++)
      {
         if (participants.get(i) == participant)
         {
            return participants.get(i).getRegisteredType(typeName);
         }
      }
      return null;
   }

   @Override
   public synchronized void registerType(Participant participant, TopicDataType topicDataType) throws IllegalArgumentException
   {
      for (int i = 0; i < participants.size(); i++)
      {
         if (participants.get(i) == participant)
         {
            participants.get(i).registerType(topicDataType);
            return;
         }
      }
      throw new IllegalArgumentException("Participant is not part of this domain.");
   }

   @Override
   public synchronized void unregisterType(Participant participant, String typeName) throws IOException
   {
      for (int i = 0; i < participants.size(); i++)
      {
         if (participants.get(i) == participant)
         {
            participants.get(i).unregisterType(typeName);
            return;
         }
      }
      throw new IllegalArgumentException("Participant is not part of this domain.");
   }

   @Override
   public synchronized void stopAll()
   {
      for (int i = participants.size() - 1; i >= 0; i--)
      {
         removeParticipant(participants.get(i));
      }
   }

   @Override
   public void setLogLevel(LogLevel level)
   {
      us.ihmc.rtps.impl.fastRTPS.LogLevel.setLogLevel(level.getLevel());
   }
   
   /**
    * Marshall a ProfilesType to a string
    * 
    * Used internally to marshall data
    * 
    * @param profile
    * @return
    * @throws IOException 
    */
   public static String marshalProfile(ProfilesType profile) throws IOException
   {
      StringWriter writer = new StringWriter();
      
      Dds dds = new Dds();
      dds.setProfiles(profile);

      try
      {
         JAXBContext context = JAXBContext.newInstance(Dds.class);
         Marshaller m = context.createMarshaller();
         m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
         m.marshal(dds, writer);
      }
      catch (JAXBException e)
      {
         e.printStackTrace();
         throw new IOException("Could not marshal XML", e);
      }

      return writer.toString();
   }

   @Override
   public List getAllParticipantsForStatistics()
   {
      return allParticipantsForStatistics;
   }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy