Robotics StackExchange | Archived questions

MoveIt! Dynamixel movement issues

Hey guys,

this is my second question in here and hopefully the first to get answered.

So I started working with Dynamixel Motors this week. I am trying to move a 5DOF arm with MoveIt!. The problem is that somehow I can't seem to smooth out the motion in any way. I updated the latency timer on the USB-Port to 1ms now the reading are at approx. 110Hz (12.5Hz with the default 16ms on Ubuntu):

    ~$ rostopic hz /motor_states/pan_tilt_port 
subscribed to [/motor_states/pan_tilt_port]
average rate: 111.085
    min: 0.007s max: 0.011s std dev: 0.00060s window: 111
average rate: 108.620
    min: 0.007s max: 0.024s std dev: 0.00153s window: 217
average rate: 108.171
    min: 0.007s max: 0.024s std dev: 0.00131s window: 324
average rate: 108.144
    min: 0.007s max: 0.024s std dev: 0.00118s window: 432
average rate: 108.132
    min: 0.006s max: 0.024s std dev: 0.00117s window: 465

So far so good I guess. The movement with 1m/s velocity seems to be somewhat smooth as seen in the attached graph:

Behavior of one of the 5 joints operated over MoveIt!

So as you can see on the graph below the position gets a lot more jumpy when I slow the movement down with velocity scaling. I also enabled the points on velocity so you can see that its in fact getting updated pretty frequently but the actual value doesn't get published as often.

Zoomed in and activated points on velocity

If Anymore information is needed I will gladly supply code or screenshots.

Hope I get the help I need. Thank you guys in advance!

Gilgamesch47


EDIT 1:

Sorry for not supplying any further information.

I will list some stuff here. The first list are all my topics. The custom topics are ARMcontroller, jointXcontroller and joint_states. The rest are moveIt generated stock ones.

    ~$ rostopic list
/ARM_controller/command
/ARM_controller/follow_joint_trajectory/cancel
/ARM_controller/follow_joint_trajectory/feedback
/ARM_controller/follow_joint_trajectory/goal
/ARM_controller/follow_joint_trajectory/result
/ARM_controller/follow_joint_trajectory/status
/ARM_controller/state
/attached_collision_object
/collision_object
/diagnostics
/display_robot_state
/execute_trajectory/cancel
/execute_trajectory/feedback
/execute_trajectory/goal
/execute_trajectory/result
/execute_trajectory/status
/joint1_controller/command
/joint1_controller/state
/joint2_controller/command
/joint2_controller/state
/joint3_controller/command
/joint3_controller/state
/joint4_controller/command
/joint4_controller/state
/joint5_controller/command
/joint5_controller/state
/joint_states
/motor_states/pan_tilt_port
/move_group/cancel
/move_group/display_contacts
/move_group/display_cost_sources
/move_group/display_grasp_markers
/move_group/display_planned_path
/move_group/feedback
/move_group/goal
/move_group/monitored_planning_scene
/move_group/motion_plan_request
/move_group/ompl/parameter_descriptions
/move_group/ompl/parameter_updates
/move_group/plan_execution/parameter_descriptions
/move_group/plan_execution/parameter_updates
/move_group/planning_scene_monitor/parameter_descriptions
/move_group/planning_scene_monitor/parameter_updates
/move_group/result
/move_group/sense_for_plan/parameter_descriptions
/move_group/sense_for_plan/parameter_updates
/move_group/status
/move_group/trajectory_execution/parameter_descriptions
/move_group/trajectory_execution/parameter_updates
/pickup/cancel
/pickup/feedback
/pickup/goal
/pickup/result
/pickup/status
/place/cancel
/place/feedback
/place/goal
/place/result
/place/status
/planning_scene
/planning_scene_world
/recognized_object_array
/rosout
/rosout_agg
/rviz_user/motionplanning_planning_scene_monitor/parameter_descriptions
/rviz_user/motionplanning_planning_scene_monitor/parameter_updates
/rviz_moveit_motion_planning_display/robot_interaction_interactive_marker_topic/feedback
/rviz_moveit_motion_planning_display/robot_interaction_interactive_marker_topic/update
/rviz_moveit_motion_planning_display/robot_interaction_interactive_marker_topic/update_full
/tf
/tf_static
/trajectory_execution_event

The nodes are as follows:

~$ rosnode list
/dynamixel_manager
/move_group
/robot_state_publisher
/rosout
/rviz_user
/state_publisher

The modified files are

my custom JointStatePublisher "state_publisher.cpp":

#include <string>
#include <math.h>
#include <ros/ros.h>
#include <sensor_msgs/JointState.h>
#include <dynamixel_msgs/MotorStateList.h>
//#include <tf/transform_broadcaster.h>

    // robot state
    double s_pan = 0, s_lift = 0, e_flex = 0, w_flex = 0, grip = 0, s_pan_vel = 0, s_lift_vel = 0, e_flex_vel = 0, w_flex_vel = 0, grip_vel = 0;


double intToRad(int pos_int){
    double buffer = (300*M_PI*pos_int)/(1023.0*180.0);
    return buffer;
}

double intToRadPerSec(int pos_int){
    double buffer = (2*M_PI*0.111*pos_int)/(60.0);
    return buffer;
}

void chatterCallback(const dynamixel_msgs::MotorStateList& msg) {

  // NEED TO CONVERT FROM ENCODER UNITS (INTEGER) TO RAD!
  s_pan = intToRad(msg.motor_states[0].position - 512);
  s_lift = intToRad(msg.motor_states[1].position - 512);
  e_flex = intToRad(msg.motor_states[2].position - 512);
  w_flex = intToRad(msg.motor_states[3].position - 512);
  grip = intToRad(msg.motor_states[4].position - 512);

    // ROS doesnt let me publish vel? -> MotState is speed in 0.111 rpm units
    // [state_publisher-3] process has died [pid 14400, exit code -11 ...
  s_pan_vel = intToRadPerSec(msg.motor_states[0].speed);
  s_lift_vel = intToRadPerSec(msg.motor_states[1].speed);
  e_flex_vel = intToRadPerSec(msg.motor_states[2].speed);
  w_flex_vel = intToRadPerSec(msg.motor_states[3].speed);
  grip_vel = intToRadPerSec(msg.motor_states[4].speed);
}

/*
MOTORSTATELIST
dynamixel_msgs/MotorState[] motor_states
  float64 timestamp
  int32 id
  int32 goal
  int32 position
  int32 error
  int32 speed
  float64 load
  float64 voltage
  int32 temperature
  bool moving


JOINTSTATE
std_msgs/Header header
  uint32 seq
  time stamp
  string frame_id
string[] name
float64[] position
float64[] velocity
float64[] effort


*/

int main(int argc, char** argv) {
    ros::init(argc, argv, "state_publisher");
    ros::init(argc, argv, "sensor_listener");
    ros::NodeHandle n;
    ros::Publisher joint_pub = n.advertise<sensor_msgs::JointState>("joint_states", 1);
    ros::Subscriber sub = n.subscribe("/motor_states/pan_tilt_port", 1000, chatterCallback);
    //tf::TransformBroadcaster broadcaster;
    ros::Rate loop_rate(5000);

    int count = 0;

    const double degree = M_PI/180.0;

    // message declarations
    sensor_msgs::JointState joint_state;

    while (ros::ok()) {
        // update joint_state
        joint_state.header.stamp = ros::Time::now();
        joint_state.name.resize(5);
        joint_state.position.resize(5);
        joint_state.velocity.resize(5);
        joint_state.name[0] ="arm_shoulder_pan_joint";
        joint_state.position[0] = s_pan;
        joint_state.velocity[0] = s_pan_vel;
        joint_state.name[1] ="arm_shoulder_lift_joint";
        joint_state.position[1] = s_lift;
    joint_state.velocity[1] = s_lift_vel;
        joint_state.name[2] ="arm_elbow_flex_joint";
        joint_state.position[2] = e_flex;
    joint_state.velocity[2] = e_flex_vel;
        joint_state.name[3] ="arm_wrist_flex_joint";
        joint_state.position[3] = w_flex;
    joint_state.velocity[3] = w_flex_vel;
        joint_state.name[4] ="gripper_joint";
        joint_state.position[4] = grip;
        joint_state.velocity[4] = grip_vel;


        // send the joint state
        joint_pub.publish(joint_state);

        ros::spinOnce();

    // fixed Rate
        loop_rate.sleep();
    }


    return 0;
}

My launch files "test_launch.launch":

<?xml version="1.0"?>
<launch>

    <arg name="debug" default="false" />

        <include file="$(find dyn_arm_2)/launch/planning_context.launch">
            <arg name="load_robot_description" value="true"/>
    </include>

    <include file="$(find dyn_arm_2)/launch/launch_sensor_and_joints.launch" />

    <include file="$(find dyn_arm_2)/launch/move_group.launch">
            <arg name="allow_trajectory_execution" value="true"/>
            <arg name="fake_execution" value="false"/>
            <arg name="info" value="true"/>
            <arg name="debug" value="$(arg debug)"/>
    </include>

    <include file="$(find dyn_arm_2)/launch/moveit_rviz.launch">
            <arg name="config" value="true"/>
            <arg name="debug" value="$(arg debug)"/>
    </include>

</launch>

and "launchsensorand_joints.launch":

<?xml version="1.0"?>
<launch>  


  <node name="dynamixel_manager" pkg="dynamixel_controllers" type="controller_manager.py" required="true" output="screen">
    <rosparam>
      namespace: dxl_manager
      serial_ports:
        pan_tilt_port:
          port_name: "/dev/ttyUSB0"
          baud_rate: 1000000
          min_motor_id: 1
          max_motor_id: 5
          update_rate: 5000
    </rosparam>
  </node>

  <node name="state_publisher" pkg="dyn_arm_2" type="state_publisher" />

  <!--node name="robot_state_publisher" pkg="robot_state_publisher" type="state_publisher" /-->

  <!-- Given the published joint states, publish tf for the robot links -->
  <node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" respawn="true" output="screen">
  <!--remap from="/joint_states" to="robot/joint_states" /-->
  <!--param name="publish_frequency" value="100.0" /-->
  </node>

<!-- Start tilt joint controller -->
    <rosparam file="$(find dyn_arm_2)/config/tilt.yaml" command="load"/>
    <node name="controller_spawner" pkg="dynamixel_controllers" type="controller_spawner.py"
          args="--manager=dxl_manager
                --port pan_tilt_port
                joint1_controller                       
                joint2_controller
                joint3_controller
                joint4_controller
                joint5_controller
                "
          output="screen"/>

  <!-- Start joints trajectory controller controller -->
    <rosparam file="$(find dyn_arm_2)/config/joints_trajectory_controller.yaml" command="load"/>
    <node name="controller_spawner_meta" pkg="dynamixel_controllers" type="controller_spawner.py"
          args="--manager=dxl_manager
                --type=meta
                ARM_controller
                joint1_controller                       
                joint2_controller
                joint3_controller
                joint4_controller
                joint5_controller
               "
          output="screen"/>

</launch>

I also added the industrialtrajectoryfilters/UniformSampleFilter to my ompl planning pipeline to smooth things out but...

Everything else is pretty much stock.


Edit 2:

Added pictures instead of links.

Asked by Gilgamesch47 on 2019-05-09 02:12:20 UTC

Comments

You don't tell us anything about which components (ie: nodes / packages) you are using to interface with the dynamixels.

I'm not sure anyone can help you without that information.

Asked by gvdhoorn on 2019-05-09 05:11:22 UTC

gvdhoorn,

Thank you for your comment. I edited my post accordingly. Sorry for the lack of information in the original post, was in a rush and frustrated.

Hope this helps you help me.

Asked by Gilgamesch47 on 2019-05-09 20:07:33 UTC

Still nobody? I desperately need help on this.

Asked by Gilgamesch47 on 2019-05-12 23:21:25 UTC

Answers