0
$\begingroup$

Rosanswers logo

Hi all,

I have been looking into ROS during the last couple of weeks, understanding how it works. I've ran it in Ubuntu (the pre-installed VirtualBox), then got it installed in OSX (Mountain Lion) and Windows 7. So for so good, things seem to work as described, and ROS looks promising.

My interest in ROS is to use it as a communication layer between several things we've been developing at my research lab (and yes, those 'things' include robots :)

However, we are not a robotics team, but an intelligent agents and synthetic characters groups, so we are used to develop on high-level platforms.

So the thing is, we develop everything in dotNet, both in Windows and OSX, and now we would like to try to link everything using ROS, because ROS offers exactly the communication mechanisms that we need. We have actually nearly built our own communication layer with the same kind of subscribe/publish mechanisms for independent 'plug-in-play' modules until we found out ROS does this and much more (like all the tools you have, and also modules for the NAO robot, which we also use)

So what I ask is suggestions for a workflow on this - making several libraries that were developed in C# to communicate over ROS.

My first bet was that I could use IronPython to get my dotnet classes to communicate with the python script that launches the ros node. The python script would add a callback to the dotnet class' events in order to publish ros messages when a certain dotnet event was launched, and would run a method on the same class with the msg information whenever a subscribed message was received.

So issue #1: I have failed to load roslib into IronPython. Does anyone know if this can be solved? Here is my execution. I first run it with python, so you see it works, things are set up correctly. However, with ipy it doesn't find roslib.

Tiago-Ribeiros-MacBook-Pro:~ tiagoribeiro$ roscd SimplePerception/

Tiago-Ribeiros-MacBook-Pro:SimplePerception tiagoribeiro$ python nodes/SimplePerceptionEffector.py

/opt/ros/fuerte/lib/python2.7/site-packages/ros_comm-1.8.12-py2.7.egg/rospy/topics.py:758: UserWarning: '\Perception\SimplePerception' is not a legal ROS graph resource name. This may cause problems with other ROS tools

[INFO] [WallTime: 1349574242.992873] hello world 1349574242.99

[INFO] [WallTime: 1349574243.994326] hello world 1349574243.99

^C

Tiago-Ribeiros-MacBook-Pro:SimplePerception tiagoribeiro$ ipy nodes/SimplePerctionEffector.py

Traceback (most recent call last):

File "nodes/SimplePerceptionEffector.py", line 5, in

ImportError: No module named roslib

Tiago-Ribeiros-MacBook-Pro:SimplePerception tiagoribeiro$

Issue #2: Even if I got this running, the WinRos Sdk is not working with python, as ROS doesn't find my package.

I failed to find a workflow on using ROS with python on windows - the tutorials point only to using cpp modules. So what should I run on windows to get ROS to find the package (assuming it's written in python)?

Issue #3: The previous issues make me realize that I might have to work with C++ and dotnet. Before I dig my hands into that, does anyone know a-priori if I won't be able to compile managed C++ with ROS? Or any suggestions on how to link my dotnet events and methods to the C++ ros interface?

Do you guys think it will build easily within visual studio?

And more - if I go on with using C++, will I have any issues while 'travelling' between a Windows environment and OSX environment? That was the main reason why I wanted to run this over IronPython.

Issue #4: Last but not least, and this is really important on our final decision of using ROS or not: Me and my colleague are building and linking together a bunch of independent modules that provide behavior and expressivity control to characters independently of their mind or body, so our packages will be used to link different minds to different robots, and event to virtual characters in Unity3D.

The purpose of this is that anyone in our labs that needs a character can use our stuff.

So even if we get this working, will we be able to redistribute our libraries running over ROS easily to someone who isn't familiarized with ROS, but just wants to use whatever we build over it?

I think this is an important question regarding my vision on the whole purpose of ROS: everything looks and works great, but it's a pain to install and setup. It definitely looks like something I don't want to depend on if I'm developing stuff for other people to use. And it is definitely something that would make me think twice before using something that depended on it - especially if I just develop cultural agents that just smile and run around inside a Unity3D scene and someone just says "hey I have this stuff here that will look great on your character, you just have to spend a couple of days going through this whole process of getting ROS to run on your machine/OS"

Is there any guide or workflow for redistributing a ROS-based library/application?

I hope I was clear on the questions. Thank you for any help!

Tiago Ribeiro


Originally posted by TiagoRibeiro on ROS Answers with karma: 41 on 2012-10-06

Post score: 0

$\endgroup$

1 Answer 1

0
$\begingroup$

Rosanswers logo

I suggest you can ask each simple question seperately to let the one who know ROS can focus.

Here is my own way to run C# program on Ubuntu with ROS nodes.

streamvis-wrappers-ros

  make c# so file
  create new package
  roscreate-pkg sam_wrappers_cs_basic roscpp topic_tools
  cd sam_wrappers_cs_basic/

  vim src/wrapper.cpp
  // Copyright c Julian Brunner 2009 - 2011
  
  // This file is part of Stream Visualizer (streamvis).
  // 
  // Stream Visualizer is free software: you can redistribute it and/or modify it
  // under the terms of the GNU General Public License as published by the Free
  // Software Foundation, either version 3 of the License, or (at your option) any
  // later version.
  // 
  // Stream Visualizer is distributed in the hope that it will be useful, but
  // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
  // details.
  // 
  // You should have received a copy of the GNU General Public License along with
  // Stream Visualizer. If not, see <http://www.gnu.org/licenses/>.
  
  #include "sam_wrappers_cs_basic/wrapper.h"
  
  #include <string>
  
  #include <ros/ros.h>
  #include <ros/serialization.h>
  #include <topic_tools/shape_shifter.h>
  
  //New
  #include "std_msgs/String.h"
  
  using namespace std;
  using namespace ros;
  using namespace ros::serialization;
  using namespace topic_tools;
  
  //New
  void chatterCallback(const std_msgs::String::ConstPtr& msg)
  {
        ROS_INFO("I heard: [%s]", msg->data.c_str());
  }
  
  extern "C" void InitializeRos(/*char* node*/)
  {
      int argc = 0;
      char** argv = NULL;
  
      //string nodeName(node);
      init(argc, argv, "IRA_CSharp_Node");
      NodeHandle n;
      Subscriber sub = n.subscribe("chatter", 1000, chatterCallback);
      spin();
  }
  
  void ShutdownRos()
  {
      shutdown();
  }
  void RosSpin()
  {
      spin();
  }
  
  //My subscriber
  extern "C" void InitializeSub(/*char* topic*/)
  {
      NodeHandle n;
  
      //string topicName(topic);
      Subscriber sub = n.subscribe("chatter", 1000, chatterCallback);
  }
  
  NodeHandle* CreateNode()
  {
      return new NodeHandle();
  }
  void DisposeNode(NodeHandle* node)
  {
      delete node;
  }
  
  Subscriber* CreateSubscriber(NodeHandle* node, const char* topicName, unsigned int queueLength, void (*callback)(ShapeShifter::ConstPtr))
  {
      return new Subscriber(node->subscribe<ShapeShifter>(topicName, queueLength, callback));
  }
  void DisposeSubscriber(Subscriber* subscriber)
  {
      delete subscriber;
  }
  
  // TODO: Memory leaks?
  const char* ShapeShifterGetDataType(const ShapeShifter::ConstPtr message)
  {
      string info = message->getDataType();
  
      char* result = new char[info.size() + 1];
      strcpy(result, info.c_str());
      return result;  
  }
  const char* ShapeShifterGetDefinition(const ShapeShifter::ConstPtr message)
  {
      string info = message->getMessageDefinition();
  
      char* result = new char[info.size() + 1];
      strcpy(result, info.c_str());
      return result;
  }
  unsigned char* ShapeShifterGetData(const ShapeShifter::ConstPtr message)
  {
      unsigned char* data = new unsigned char[message->size()];
  
      OStream stream(data, message->size());
      message->write(stream);
  
      return data;
  }
  unsigned int ShapeShifterGetDataLength(const ShapeShifter::ConstPtr message)
  {
      return message->size();
  }
  vim include/sam_wrappers_cs_basic/wrapper.h
  // Copyright c Julian Brunner 2009 - 2011
  
  // This file is part of Stream Visualizer (streamvis).
  // 
  // Stream Visualizer is free software: you can redistribute it and/or modify it
  // under the terms of the GNU General Public License as published by the Free
  // Software Foundation, either version 3 of the License, or (at your option) any
  // later version.
  // 
  // Stream Visualizer is distributed in the hope that it will be useful, but
  // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
  // details.
  // 
  // You should have received a copy of the GNU General Public License along with
  // Stream Visualizer. If not, see <http://www.gnu.org/licenses/>.
  
  #ifndef __STREAMVIS_WRAPPERS_ROS_H__
  #define __STREAMVIS_WRAPPERS_ROS_H__
  
  #include <ros/ros.h>
  #include <topic_tools/shape_shifter.h>
  
  using namespace ros;
  using namespace topic_tools;
  
  extern "C"
  {
      void InitializeRos();
      void ShutdownRos();
      void RosSpin();
  
      NodeHandle* CreateNode();
      void DisposeNode(NodeHandle* node);
  
      Subscriber* CreateSubscriber(NodeHandle* node, const char* topicName, unsigned int queueLength, void (*callback)(const ShapeShifter::ConstPtr));
      void DisposeSubscriber(Subscriber* subscriber);
  
      const char* ShapeShifterGetDataType(const ShapeShifter::ConstPtr message);
      const char* ShapeShifterGetDefinition(const ShapeShifter::ConstPtr message);
      unsigned char* ShapeShifterGetData(const ShapeShifter::ConstPtr message);
      unsigned int ShapeShifterGetDataLength(const ShapeShifter::ConstPtr messsage);
  }
  
  #endif

  vim CMakeLists.txt
  cmake_minimum_required(VERSION 2.4.6)
  include($ENV{ROS_ROOT}/core/rosbuild/rosbuild.cmake)
  
  # Set the build type.  Options are:
  #  Coverage       : w/ debug symbols, w/o optimization, w/ code-coverage
  #  Debug          : w/ debug symbols, w/o optimization
  #  Release        : w/o debug symbols, w/ optimization
  #  RelWithDebInfo : w/ debug symbols, w/ optimization
  #  MinSizeRel     : w/o debug symbols, w/ optimization, stripped binaries
  #set(ROS_BUILD_TYPE RelWithDebInfo)
  
  rosbuild_init()
  
  #set the default path for built executables to the "bin" directory
  set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
  #set the default path for built libraries to the "lib" directory
  set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
  
  #uncomment if you have defined messages
  #rosbuild_genmsg()
  #uncomment if you have defined services
  #rosbuild_gensrv()
  
  #common commands for building c++ executables and libraries
  #rosbuild_add_library(${PROJECT_NAME} src/example.cpp)
  #target_link_libraries(${PROJECT_NAME} another_library)
  #rosbuild_add_boost_directories()
  #rosbuild_link_boost(${PROJECT_NAME} thread)
  #rosbuild_add_executable(example examples/example.cpp)
  #target_link_libraries(example ${PROJECT_NAME})
  rosbuild_add_library(${PROJECT_NAME} src/wrapper.cpp)

  rosmake
  Now it will generate libsam_wrappers_cs_basic.so
  
  Test that so file
  mkdir test
  cd test/
  copy that so file
  cp ../lib/libsam_wrappers_cs_basic.so .
  vim ros_init.cs
  using System;
  using System.Diagnostics;
  using System.Runtime.InteropServices;
  using System.Text.RegularExpressions;
  using System.Threading;
  using Data.Ros;
  
  namespace Data.Ros
  {
      public class RosNetwork 
      {
          static public void Main ()
          {   
              InitializeRos();
              //InitializeSub();
              //RosSpin();    
          }   
  
          [DllImport("libsam_wrappers_cs_basic")]
          static extern void InitializeRos(/*string node*/);
  /*
          [DllImport("streamvis-wrappers-ros")]
          static extern void InitializeSub(string topic);
  
          [DllImport("streamvis-wrappers-ros")]
          static extern void RosSpin();
  */
      }
  }
  use mono to compile .cs program to generate ros_init.exe
  gmcs ros_init.cs
  run talker
  rostopic pub /chatter std_msgs/String -r 5 "abcde"
  get the result
  ira@ira-K42JP:~/code/ros/sam_cs/sam_wrappers_cs_basic/test$ ./ros_init.exe 
  [ INFO] [1345021492.310405185]: I heard: [abcde]
  [ INFO] [1345021492.510243616]: I heard: [abcde]
  [ INFO] [1345021492.710016020]: I heard: [abcde]
  …
  you can view on rxgraph
   
  
  
                                                                                

Originally posted by sam with karma: 2570 on 2012-10-06

This answer was ACCEPTED on the original site

Post score: 2

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.