hbrobotics / ros_arduino_bridge

ROS + Arduino = Robot
355 stars 351 forks source link

How to get encoder position in ros node? #33

Closed roboticsai closed 7 years ago

roboticsai commented 7 years ago

I am reading the encoder pins by using the ros arduino bridge, where i am subscribing to the encoder pins inside my ros node i.e a c++ program. Here every time a new pin value arrives in program all its variables are reset. But as i saw the encoder programs one variable has to store the privious encoder position, so how can it be done in c++. The arduino program to read encoder is:

[
/* Rotary encoder read example */
#define ENC_A 14
#define ENC_B 15
#define ENC_PORT PINC

void setup()
{
  /* Setup encoder pins as inputs */
  pinMode(ENC_A, INPUT);
  digitalWrite(ENC_A, HIGH);
  pinMode(ENC_B, INPUT);
  digitalWrite(ENC_B, HIGH);
  Serial.begin (115200);
  Serial.println("Start");
}

void loop()
{
 static uint8_t counter = 0;      //this variable will be changed by encoder input
 int8_t tmpdata;
 /**/
  tmpdata = read_encoder();
  if( tmpdata ) {
    Serial.print("Counter value: ");
    Serial.print(counter, DEC);
    counter += tmpdata;
  }
}

/* returns change in encoder state (-1,0,1) */
int8_t read_encoder()
{
  static int8_t enc_states[] = {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0};
  static uint8_t old_AB = 0;
  /**/
  old_AB <<= 2;                   //remember previous state
  old_AB |= ( ENC_PORT & 0x03 );  //add current state
  return ( enc_states[( old_AB & 0x0f )]);
}](url)
/* Rotary encoder read example */
#define ENC_A 14
#define ENC_B 15
#define ENC_PORT PINC

void setup()
{
  /* Setup encoder pins as inputs */
  pinMode(ENC_A, INPUT);
  digitalWrite(ENC_A, HIGH);
  pinMode(ENC_B, INPUT);
  digitalWrite(ENC_B, HIGH);
  Serial.begin (115200);
  Serial.println("Start");
}

void loop()
{
 static uint8_t counter = 0;      //this variable will be changed by encoder input
 int8_t tmpdata;
 /**/
  tmpdata = read_encoder();
  if( tmpdata ) {
    Serial.print("Counter value: ");
    Serial.print(counter, DEC);
    counter += tmpdata;
  }
}

/* returns change in encoder state (-1,0,1) */
int8_t read_encoder()
{
  static int8_t enc_states[] = {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0};
  static uint8_t old_AB = 0;
  /**/
  old_AB <<= 2;                   //remember previous state
  old_AB |= ( ENC_PORT & 0x03 );  //add current state
  return ( enc_states[( old_AB & 0x0f )]);
}](url)returns change in encoder state (-1,0,1) */
int8_t read_encoder()
{
  static int8_t enc_states[] = {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0};
  static uint8_t old_AB = 0;
  /**/
  old_AB <<= 2;                   //remember previous state
  old_AB |= ( ENC_PORT & 0x03 );  //add current state
  return ( enc_states[( old_AB & 0x0f )]);
}](url)

Currentely my roscpp program is:

[#include <message_filters/subscriber.h>
#include <message_filters/time_synchronizer.h>
#include <sensor_msgs/Image.h>
#include <sensor_msgs/CameraInfo.h>
#include <iostream>
#include <ros_arduino_msgs/Digital.h>
using namespace ros_arduino_msgs;
using namespace message_filters;

void callback(const DigitalConstPtr& e1, const DigitalConstPtr& e2)
{ 
  std::cout<<"callback"<<std::endl;
  std::cout<<e1<<std::endl;
}

int main(int argc, char** argv)
{
  ros::init(argc, argv, "vision_node");
  std::cout<<"main"<<std::endl;
  ros::NodeHandle nh;
  message_filters::Subscriber<Digital> e1(nh, "/arduino/sensor/left_encoder_A", 10);
  message_filters::Subscriber<Digital> e2(nh, "/arduino/sensor/left_encoder_B", 10);
  TimeSynchronizer<Digital, Digital> sync(e1, e2, 10);
  sync.registerCallback(boost::bind(&callback, _1, _2));

  ros::spin();

  return 0;
}](url)

Now in the callback function how do i program the encoder? Here since every time the ros node subscribes to a new topic all the parameters inside the program is also reset, i am getting the problem.