Skip to content

Commit

Permalink
Parameter Node added to new Helper module.
Browse files Browse the repository at this point in the history
  • Loading branch information
Juan Ignacio Ubeira committed Feb 20, 2017
1 parent fe2b833 commit 6e5dd10
Show file tree
Hide file tree
Showing 3 changed files with 146 additions and 1 deletion.
6 changes: 6 additions & 0 deletions rosjava_helpers/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
apply plugin: 'java'

dependencies {
compile project(':rosjava')
compile 'org.yaml:snakeyaml:[1.17, 1.18)'
}
138 changes: 138 additions & 0 deletions rosjava_helpers/src/main/java/org/ros/helpers/ParameterLoaderNode.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
/*
* Copyright 2017 Ekumen, Inc. All Rights Reserved.
*
* 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 org.ros.helpers;

import org.apache.commons.logging.Log;
import org.ros.namespace.GraphName;
import org.ros.node.AbstractNodeMain;
import org.ros.node.ConnectedNode;
import org.ros.node.parameter.ParameterTree;
import org.yaml.snakeyaml.Yaml;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
* Loads parameters from Yaml files into the ROS parameter server.
* A different namespace can be specified for each of the files to load.
* To use this node, create a {@link Resource} list with the resources to load,
* and start it in the standard RosJava way.
*
* @author [email protected] (Lucas Chiesa).
* Modified by [email protected] (Juan I. Ubeira)
*/
public class ParameterLoaderNode extends AbstractNodeMain {

public static final String NODE_NAME = "parameter_loader";
private final List<LoadedResource> params = new ArrayList<>();
private Log log;

/**
* Default constructor
* @param resources Array of resources with their respective namespace to load.
*/
public ParameterLoaderNode(ArrayList<Resource> resources) {
for (Resource r : resources) {
addSingleYmlInput(r.inputStream, r.namespace == null ? "" : r.namespace);
}
}

private void addSingleYmlInput(InputStream ymlInputStream, String namespace) {
this.params.add(new LoadedResource((new Yaml()).load(ymlInputStream), namespace));
}

private void addParams(ParameterTree parameterTree, String namespace, Map<String, Object> params) {
for (Map.Entry<String, Object> e : params.entrySet()) {
String fullKeyName = namespace + "/" + e.getKey();
if (log != null) {
log.info("Loading parameter " + fullKeyName + " \nValue = " + e.getValue());
}

if (e.getValue() instanceof String) {
parameterTree.set(fullKeyName, (String)e.getValue());
} else if (e.getValue() instanceof Integer) {
parameterTree.set(fullKeyName, (Integer)e.getValue());
} else if (e.getValue() instanceof Double) {
parameterTree.set(fullKeyName, (Double)e.getValue());
} else if (e.getValue() instanceof Map) {
parameterTree.set(fullKeyName, (Map)e.getValue());
} else if (e.getValue() instanceof Boolean) {
parameterTree.set(fullKeyName, (Boolean)e.getValue());
} else if (e.getValue() instanceof List) {
parameterTree.set(fullKeyName, (List)e.getValue());
} else if (log != null) {
log.debug("I don't know what type parameter " + fullKeyName + " is. Value = " + e.getValue());
log.debug("Class name is: " + e.getValue().getClass().getName());
}
}
}

/**
* @return the name of the Node that will be used if a name was not
* specified in the Node's associated NodeConfiguration.
*/
@Override
public GraphName getDefaultNodeName() {
return GraphName.of(NODE_NAME);
}

@Override
public void onStart(ConnectedNode connectedNode) {
if (params != null) {
ParameterTree parameterTree = connectedNode.getParameterTree();
log = connectedNode.getLog();

// TODO: For some reason, setting the / param when using a rosjava master doesn't work
// It does work fine with an external master, and also setting other params of any type
for (LoadedResource r : params) {
addParams(parameterTree, r.namespace, r.resource);
}

connectedNode.shutdown();
}
}

/**
* Resource to load to Parameter Server, consisting of an InputStream and its corresponding namespace.
*/
public static class Resource {
public InputStream inputStream;
public String namespace;

public Resource(InputStream inputStream, String namespace) {
this.inputStream = inputStream;
this.namespace = namespace;
}
}

/**
* Thin wrapper for the object returned by Yaml.load().
* The object returned by Yaml.load() is a LinkedHashMap<String, Object>; this class is to
* keep the code simple.
*/
private class LoadedResource {
public Map<String, Object> resource;
public String namespace;

LoadedResource(Object resource, String namespace) {
this.resource = (Map<String, Object>) resource;
this.namespace = namespace;
}
}
}
3 changes: 2 additions & 1 deletion settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,10 @@ include(
'rosjava_geometry',
'rosjava_benchmarks',
'rosjava_test',
'rosjava_helpers',
'rosjava_tutorial_pubsub',
'rosjava_tutorial_right_hand_rule',
'rosjava_tutorial_services',
'docs',
)
)

0 comments on commit 6e5dd10

Please sign in to comment.