ros2-java / ros2_java

Java and Android bindings for ROS2
Apache License 2.0
172 stars 93 forks source link

Add Spring boot Support #244

Open Ekk9 opened 3 months ago

Ekk9 commented 3 months ago

Currently I have a program where I want to use ros2-java, but in a spring boot project. Currently I'm making good progress in using ros2-java compiled artifacts to pull into my spring boot gradle project, but it's not documented how to do this anywhere and I'm having to figure out how to do this.

Would it be possible to add Spring-boot support?

Here's what I have currently, it uses jars created by ros2-java + jnis generated as part of the build process. I've been testing with the Ros2SubscriberLambda.java from ros2-java-examples. I'll add the build.gradle + the application and configuration java classes in the comments.

Ekk9 commented 3 months ago

build.gradle:

plugins {
id 'org.springframework.boot' version '2.7.9'
}

apply plugin: 'java'
apply plugin: 'org.springframework.boot'

repositories {
mavenCentral()
}

dependencies {
implementation files('libs/rcljava.jar', 'libs/rcljava_common.jar', 'libs/std_msgs_messages.jar', 'libs/diagnostic_msgs_messages.jar')
implementation 'org.springframework.boot:spring-boot-starter-web:2.7.9'
}

bootRun {
systemProperty 'java.library.path', '/ros2_java_ws/install/rcljava/lib/jni:/workspaces/rosie/ros2_java_ws/install/std_msgs/lib/jni:/ros2_java_ws/install/diagnostic_msgs/lib/jni'
}
Ekk9 commented 3 months ago

Ros2SubscriberApplication (Spring-boot's main):

package com.ros2.subscriber;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Import;

/**
 * Main class to start application
 */
@SpringBootApplication
@Import({Ros2SubscriberConfiguration.class})
public class Ros2SubscriberApplication
{

  public static ConfigurableApplicationContext applicationContext;

  public static void main(String[] args)
  {
    SpringApplication.run(Ros2SubscriberApplication.class, args);
  }

}

Ros2SubscriberConfiguration:

package com.ros2.subscriber;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.ComponentScan;

@ComponentScan(basePackages = {"com.cobch.ros2subscriber"})
@ConfigurationProperties
public class Ros2SubscriberConfiguration {}

Ros2SubscriberManager:

package com.ros2.subscriber;

import org.ros2.rcljava.RCLJava;
import org.springframework.stereotype.Component;

@Component
public class Ros2SubscriberManager {

  public Ros2SubscriberManager() {
    RCLJava.rclJavaInit();

    RCLJava.spin(new Ros2Subscriber());
  }
}

Ros2Subscriber:

package com.cobch.ros2.subscriber;

import org.ros2.rcljava.node.BaseComposableNode;
import org.ros2.rcljava.subscription.Subscription;

public class Ros2Subscriber extends BaseComposableNode
{

  private Subscription<diagnostic_msgs.msg.KeyValue> subscription;

  public Ros2Subscriber()
  {
    super("minimal_subscriber");
    subscription = node.< diagnostic_msgs.msg.KeyValue > createSubscription(
      diagnostic_msgs.msg.KeyValue.class, "topic",
      msg -> System.out.println("I heard: [" + msg.getKey() + " " + msg.getValue() + "]"));
  }
}