Skip to content
This repository has been archived by the owner on Feb 3, 2023. It is now read-only.

Rosserial Integration #111

Open
CanyonTurtle opened this issue Jul 19, 2018 · 2 comments
Open

Rosserial Integration #111

CanyonTurtle opened this issue Jul 19, 2018 · 2 comments

Comments

@CanyonTurtle
Copy link

CanyonTurtle commented Jul 19, 2018

Is your feature request related to a problem? Please describe.

Problem: Integrating a ROS serial connection with VEX hardware is possible with rosserial for V5 alone, but requires user configuration for lots of hardware-specific setup, such as setting up publishers for sensor data, moving the robot based on commands, etc...

Describe the solution you'd like

The OkapiLib API can act as a schema for mapping ROS objects into abstractions, e.g. chassis, that ROS can control via standardized ROS messages, e.g. Twist command velocity messages for that chassis.

Describe alternatives you've considered

Using rosserial with vex hardware is still possible (example), but the OkapiLib abstractions can provide control systems built-in, which will allow the ROS messages to be a more intelligent control interface, with minimal user requirement.

Versions

PROS: 3.0.6
OkapiLib: recent

Additional context

This issue is intended to be a running discussion about integrating rosserial and OkapiLib.

@CanyonTurtle
Copy link
Author

CanyonTurtle commented Jul 20, 2018

Some additional summary of our initial discussion @Octogonapus:

Design of Adaptation Layer as Registry / Class Wrappers

There are a few ways to make some sort of adaptation layer for rosserial bindings ontop of the OkapiLib classes.

1 - Create a registry class that accepts OkapiLib objects.

The registry class assigns the required publishers/subscribers to track the OkapiLib with publishers and subscriber callbacks. The registry would presumably have an overridden method for "register" for each supported OkapiLib class that would be the mechanism for writing the ROS binding behavior.

rosserial::Registry rosManager; 

void opcontrol(void) {
  // set up loop thread to publish sensor data from all registered objects
  rosManager.start(20);
  
  // Normal OkapiLib object definition
  // ...
  okapi::ChasisController chassis(model);
  // ...

  // every 20 milliseconds, sensor array published on topic , e.g. "/myDrive/sensors/"
  // AND subscriber callbacks are set for another topic, e.g. "myDrive/cmd_vel/"
  // Note: these names are all just placeholders
  rosManager.register(chassis, "myDrive");
  // the above requires implementation of 
  // void rosserial::Registry::register(okapi::ChassisController, const char*);
  // AND
  // void rosserial::Registry::ChassisControllerCallback(const geometry_msgs::Twist&);
}

1 PROS (no pun intended):

  • Don't have to make new class for every time we want to wrap one from OkapiLib
  • Straightforward way for the user to bind the parts he wants.

1 CONS

  • lots of stuff in the Registry class
  • explicit declaration of a manager and of registering

2 - Create rosserial subclasses of OkapiLib objects.

There would be one subclass for every supported OkapiLib class that extends the original with the ROS functionality.

void opcontrol(void) {
  
  // Normal OkapiLib object definition
  okapi::ChasisController chassis(model);

  // every 20 milliseconds, sensor array published on topic , e.g. "/myDrive/sensors/"
  // AND subscriber callbacks are set for another topic, e.g. "myDrive/cmd_vel/"
  rosserial::wrappers::ChassisController rosChassis(chassis, "myDrive");
  // the class has the pub/sub logic from before, but in the class
}

2 PROS:

  • behavior per-subsystem will clearly associate in a respective class

2 CONS:

  • User API more diverse. More to know?
  • setting up publishers and subscribers probably requires a dedicated singleton thread anyway (workaround: multiple inheritance, so the rosserial subclasses inherit from the OkapiLib class, and a single ROS class with a method to set up publishers in that singleton thread).

These approaches are similar in nature, after all. I think that the first way has a cleaner interface.

Configuration for Registered objects

When an OkapiLib object is registered, additional configuration should be provided.
At least:

  • the name of the object, as will be visible via ROS topics
  • maybe, publish rate? V5 is fast enough to do everything at 100hz, we could just
    use the publishing loop to decide how fast the whole system will go.
  • What to publish / subcribe: I actually think these don't need to be parameters. A given system should have fixed publishers / subscribers, that will be implemented in the respective register() function, and can be documented to show how to interface over ROS with that subsystem.

Additional notes

This architecture makes it very straightforward how to handle the API: every supported object has a correspondingregister() override in the Registry class, everyget() has a publisher constantly firing in that registry's loop thread, and every set() has a subscriber callback waiting for a ros message to pass parameters. Possibly, an option in registering to make some parts of a system silent might be good. Or, forcing the user to supply which messages to send/recieve could reduce unnecessary messages.

@Octogonapus
Copy link
Member

As I had said before, I prefer the first option. Others are welcome to share their opinions.

@Octogonapus Octogonapus added this to Backlog in Main OkapiLib Development via automation Sep 15, 2018
@Octogonapus Octogonapus moved this from Backlog to Freezer in Main OkapiLib Development Sep 15, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
Development

No branches or pull requests

2 participants