Syncing Arduino motor movements with Rviz "joint_states"

asked 2020-07-08 22:09:33 -0500

20sffactory gravatar image

Hi, I am using rosserial_arduino to connect to Rviz running Moveit plugin. In Rviz, I can move the URDF and execute motion planning, by subscribing to ROS topic "joint_states" on Arduino, the NEMA17 motors run as expected.

in my case shown this video: Robot Experiment with ROS Moveit, the motor movements don't sync with the continuous movements RVIZ, resulting in chopped up movements instead of one smooth flow.

How can I change the way Arduino process "joint_states" in order for the stepper motors to move in sync with Rviz? Or is the default rviz "joint_states" topic an ideal way to directly drive a robot?

I'm a total beginner in ROS and doing my reading in other ROS nodes and methods which can be applied to my scenario. I wish to seek help or referral to any reading links. Thank you very much.

Here is the codes I use on my Arduino driving 3 stepper motors:

#include "pinout.h"

#include <ros.h>
#include <std_msgs/Int32.h>
#include <std_msgs/Bool.h>
#include <sensor_msgs/JointState.h>
#include <AccelStepper.h>
#include <MultiStepper.h>

//Baud Rate Declarations
#define BAUD 115200

//Stepper Configurations
#define NEMA_17_COUNT 3
#define STEPS_REVOLUTE 3200
#define STEPPER_SPEED 1000

int pulley_teeth_count = 20;
int gear_teeth_count = 90;
double gearRatio = (double)gear_teeth_count / (double)pulley_teeth_count;

int radianToSteps(double radian){
  double radian_360 = 4 * acos(0.0);
  int steps = STEPS_REVOLUTE * gearRatio * radian / radian_360;
  return steps;
}
//Stepper Instances & Functions
int stepsRotation[NEMA_17_COUNT] = {STEPS_REVOLUTE, STEPS_REVOLUTE, STEPS_REVOLUTE};
int stepperDirection[NEMA_17_COUNT] = {1, 1, 1};

AccelStepper joint1(1, ROT_STEP_PIN, ROT_DIR_PIN);
AccelStepper joint2(1, LOW_ARM_STEP_PIN, LOW_ARM_DIR_PIN);
AccelStepper joint3(1, UP_ARM_STEP_PIN, UP_ARM_DIR_PIN);

void pinActivation(){
  pinMode(ROT_ENABLE_PIN,OUTPUT);
  pinMode(UP_ARM_ENABLE_PIN,OUTPUT);
  pinMode(LOW_ARM_ENABLE_PIN,OUTPUT);
  digitalWrite(ROT_ENABLE_PIN, LOW);
  digitalWrite(LOW_ARM_ENABLE_PIN, LOW);
  digitalWrite(UP_ARM_ENABLE_PIN, LOW);    
  pinMode(FAN_PIN, OUTPUT);
  digitalWrite(FAN_PIN, HIGH);
}

MultiStepper steppers;
int joint_step[3] = {};
int joint_status = 0;

void motors_cb(const sensor_msgs::JointState& arm_radian) {
  joint_status = 1;
  joint_step[0] = radianToSteps(arm_radian.position[0]);
  joint_step[1] = radianToSteps(arm_radian.position[1]);
  joint_step[2] = radianToSteps(arm_radian.position[3]); // skipping lower_virtualupper joint
  }

//ROS Declarations
ros::NodeHandle node_handle;
ros::Subscriber<sensor_msgs::JointState> joint_states("joint_states", motors_cb);

void setup(){
  pinActivation();
  node_handle.getHardware()->setBaud(BAUD);
  node_handle.initNode();
  node_handle.subscribe(joint_states);
  joint1.setMaxSpeed(STEPPER_SPEED);
  joint2.setMaxSpeed(STEPPER_SPEED);
  joint3.setMaxSpeed(STEPPER_SPEED);
  steppers.addStepper(joint1);
  steppers.addStepper(joint2);
  steppers.addStepper(joint3);
}

void loop(){
  if (joint_status == 1){  
    long position[3];
    position[0] = stepperDirection[0] * joint_step[0];
    position[1] = stepperDirection[1] * joint_step[1];
    position[2] = stepperDirection[2] * joint_step[2];
    steppers.moveTo(position);
    node_handle.spinOnce();
    steppers.runSpeedToPosition();
  }
  joint_status = 0;
  node_handle.spinOnce();
  delay(1);
}
edit retag flag offensive close merge delete

Comments

Did u solve it

Hosam gravatar image Hosam  ( 2020-08-07 18:08:15 -0500 )edit

I ended up using customised Marlin 1.1.x as the receiving end on Arduino which seems much smoother. Still under experiment and tweaking.

20sffactory gravatar image 20sffactory  ( 2020-08-11 02:22:19 -0500 )edit