Skip to content

How to contribute?

NRottmann edited this page Apr 8, 2021 · 17 revisions

In this section we present the different ways you can contribute to the ROS Mobile project. There are three ways: You can become a full-fledged project member, you can add your own nodes and submit a pull request, or you can simply make suggestions for improvements that will help us further improve ROS-Mobile. Each of the options requires a different level of commitment.

Table of Contents

Become a project member

If you think this is a really nice project, you have some free time, and you're reasonably comfortable working with Java and ROS, then you might want to join our project team as a full member. Feel free to contact us:
rosmobile.info(at)gmail.com

Add your own widgets and layers

If you like to add your own nodes to the app and contribute them to the project, we recommend the following procedure:

Copy the project

  • Fork the repository to your own GitHub account by hitting the fork button at the upper right corner.
  • Download the repository to your PC, e.g. using
git clone https://github.com/yourUserName/ROS-Mobile-Android.git

Create a new widget

The core of the app consists of one or multiple configurations created by the app based on its needs. To this configuration multiple widgets and labels can be added to allow debugging, controlling or visualizing different things, e.g. to steer a robot with a virtual joystick, view its camera output or debug data.

Definitions

Note that as of app version 2.0 widgets and layers exist. Here is a short definition:

Widget:

  • A widget can be used as an independent tool to visualize different data. It has its own position and size preferences inside the Viz tab of the App.

Layer:

  • A layer is a sub part of a widget like the Viz2D widget. Its position and size is determined and controlled by its parent widget. Layers can be stacked, with the drawing hierarchy depending on the order in which they are added. That means that the first added layer will be drawn as the bottom layer in the widget.

You have to decide if you want to create a layer or a widget (for this tutorial we will use Type as an identifier in the following). Furthermore you should define its interaction with the ROS-System. There are three different interaction possibilities for which we use the identifier Interaction:

Subscriber:  Subscribes to a topic (e.g. Map layer)
Publisher:    Publishes to a topic (e.g. Joystick widget)
Hidden:        Does not interact with the ROS-System in any way (e.g. Label widget)

Implementation

In order to create a new widget or layer, you have to implement some basic classes to define all necessary properties. To avoid loading and execution problems, follow the naming convention. We will use Name in the following as a generic identifier for your widget name.

  1. Folder
    First, you have to add a new folder name (lowercase) in com/schneewittchen/rosandroid/widgets. For example: com/schneewittchen/rosandroid/widgets/joystick

  2. Entity class
    Create an entity class where all of the object properties will be defined. This class is responsible for saving and loading your Type from the storage. The class name has to be NameEntity extending InteractionTypeEntity. Additionally add a constructor with all default object values. Of course, this depends highly on the Type and Interaction you have chosen.

package com.schneewittchen.rosandroid.widgets.joystick;


public class JoystickEntity extends PublisherWidgetEntity {

  public JoystickEntity() {
      this.width = 4;
      this.height = 4;
      this.topic = new Topic("cmd_vel", Twist._TYPE);
  }
}
  1. Detail viewholder class
    Create a detail viewholder class, which represents and interacts with the entity properties in the detail tab of the app. The class name has to be NameDetailVH extending InteractionTypeDetailVH. Implement all the necessary overwritten methods.
package com.schneewittchen.rosandroid.widgets.joystick;


public class JoystickDetailVH extends PublisherWidgetViewHolder {

    @Override
    public void initView(View view) {
    }

    @Override
    public void bindEntity(BaseEntity entity) {
    }


    @Override
    public void updateEntity(BaseEntity entity) {
    }

    @Override
    public List<String> getTopicTypes() {
        return Collections.singletonList(Twist._TYPE);
    }
}
  1. View class
    Create a view class, which is responsible for the drawing process in the Viz tab of the app. The class name has to be NameView extending InteractionTypeView. Implement all the necessary overwritten methods.
package com.schneewittchen.rosandroid.widgets.joystick;


public class JoystickView extends PublisherWidgetView {

    public JoystickView(Context context) {
        super(context);
    }

    public JoystickView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return true;
    }

    @Override
    public void onDraw(Canvas canvas) {
    }
}
  1. Description
    To be able to add your Type to your configuration, you have to tell the app that it is existing. By adding the name and description to the res/values/widget.xml, the app can finally show and interact with your Type. Extend the string-array _Typenames with your created Name. Further, add a description to make sure that the app user knows what your Type is able to do.
<!-- Joystick -->
<string name="Joystick_description">
    This is your desciption.
</string>
  1. Check and debug
    Compile the app and your widget or layer should appear in one of the drop-down lists in the Details tab of the app. If it is a layer, you must first add a parent widget such as a Viz2D. If something doesn't work as expected, please first check that you have done all the naming conventions correctly - they are indeed case sensitive.

Share your contributions

If you are satisfied with your node creation and want to share it with the community, create a pull request to our master branch How to add your branch to our master:

Step 1: Add the remote (original repo that you forked) and call it “upstream”

    git remote add upstream https://github.com/original-repo/goes-here.git

Step 2: Fetch all branches of remote upstream

    git fetch upstream

Step 3: Rewrite your master with upstream’s master using git rebase.

    git rebase upstream/master

Step 4: Push your updates to master. You may need to force the push with “--force”.

    git push origin master --force

Make improvement suggestions

If you found a bug, have a new feature request, require a new widget or more, feel free to add a new issue [here](https://github.com/ROS-Mobile/ROS-Mobile-Android/issues).