How to use ROS Control on real robot?
Hi everyone,
I would like to control the motor/servo motor using ros_control.
I did courses at robotingiteacademy
, but I can't understand practically what I should do now.
I need information how to read and transmit data from the encoder to ROS and how to send data to the engine to be able to control it.
I would be grateful for also example.
I put my code.
#define ROSSERIAL_ARDUINO_TCP
#include <Timers.h>
#include <ros.h>
#include <std_msgs/String.h>
#include <std_msgs/Float64.h>
byte mac[]= {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
IPAddress ip(10,3,2,25);
IPAddress server(10,3,2,51);
// Set the rosserial socket server port
const uint16_t serverPort = 11411;
void ros_set_current_limit( const std_msgs::Float64& cmd_msg); void ros_set_temp_limit( const std_msgs::Float64&
cmd_msg); void ros_set_joint_min_position( const std_msgs::Float64& cmd_msg); void ros_set_joint_max_position(
const std_msgs::Float64& cmd_msg); void ros_set_joint_position( const std_msgs::Float64& cmd_msg); float
read_ADC(int pin, int ilosc_odczytow=1, bool odrzuc_brzegowe=0);
// CONSTANTS
const byte pin_TE = A1;
// VARIABLES
// ROS
ros::NodeHandle nh;
std_msgs::Float64 adc_msg;
Timer timer_adc_cs;
float odczytADC_CS = 0.0; // aktualna wartosc czujnika pradu float odczytADC_TE = 0.0;
temperatury float odczytADC_EN = 0.0;
// Wartosci brzegowe
float max_current = 10.0;
bool wystapila_komunikacja = 0;
- SECURITY
// Publishers
ros::Publisher publish_te("/sensors/temp/get", &adc_msg); ros::Publisher publish_cs("/sensors/current/get",
&adc_msg); ros::Publisher publish_en("/sensors/encoder/get", &adc_msg);
// Subscribers
ros::Subscriber <std_msgs::Float64>
subscriber_set_current_limit("/sensors/current/limit/set",
ros_set_current_limit);
ros::Subscriber <std_msgs::Float64>
subscriber_set_temp_limit("/sensors/temp/limit/set", ros_set_temp_limit); ros::Subscriber <std_msgs::Float64>
subscriber_set_joint_position("/joint_position/set",
ros_set_joint_position);
ros::Subscriber <std_msgs::Float64>
subscriber_set_joint_min_position("/joint_position/min/set",
ros_set_joint_min_position);
ros::Subscriber <std_msgs::Float64>
subscriber_set_joint_max_position("/joint_position/max/set",
ros_set_joint_max_position);
// SETUP
void setup() {
Serial.begin(115200);
Ethernet.begin(mac, ip);
Serial.println("aa");
// DC Motor D9 (16bit), D4, D7
// analogWriteResolution(12);
pinMode(pin_PWM, OUTPUT);
pinMode(pin_DCL, OUTPUT);
pinMode(pin_DCR, OUTPUT);
// // ADC A0, A1, A2
pinMode(pin_CS, INPUT);
pinMode(pin_TE, INPUT);
pinMode(pin_EN, INPUT);
nh.getHardware()->setConnection(server, serverPort);
nh.initNode();
delay(1000);
nh.advertise(publish_cs);
nh.advertise(publish_te);
nh.advertise(publish_en);
nh.subscribe(subscriber_set_temp_limit);
nh.subscribe(subscriber_set_current_limit);
nh.subscribe(subscriber_set_joint_position);
nh.subscribe(subscriber_set_joint_min_position);
nh.subscribe(subscriber_set_joint_max_position);
delay(1000);
timer_adc_cs.begin(FREQ(czestotliwosc_ADC_CS));
timer_adc_te.begin(FREQ(czestotliwosc_ADC_TE));
timer_adc_en.begin(FREQ(czestotliwosc_ADC_EN));
timer_sec.begin(FREQ(czestotliwosc_SEC));
}
// LOOP
void loop() {
// ADC READ - temperature sensor
if (timer_adc_te.available())ty
{
// int bledy = timer_adc_cs.errors();
odczytADC_TE = read_ADC(pin_TE, 10, 1);
// Wyslanie komunikatu ROS
adc_msg.data = odczytADC_TE;
publish_te.publish(&adc_msg);
nh.spinOnce();
// timer_adc.resetErrors();
}
// ADC READ - current sensor
if (timer_adc_cs.available())
{
// int bledy = timer_adc_cs.errors();
odczytADC_CS = read_ADC(pin_CS, 10, 1);
adc_msg.data = odczytADC_CS;
// Wyslanie komunikatu ROS
publish_cs.publish(&adc_msg);
nh.spinOnce();
// timer_adc.resetErrors();
}
// ADC READ - motor encoder
if (timer_adc_en.available())
{
// int bledy = timer_adc_cs.errors();
odczytADC_EN = read_ADC(pin_EN, 10, 1);
// Konwersja z ADC na wartosc odchylenia
// adc_msg.data = 1.456;
adc_msg.data = (odczytADC_EN / 1024) * 100;
// Wyslanie komunikatu ROS
publish_en.publish(&adc_msg);
nh.spinOnce();
// timer_adc.resetErrors();
}
// SECURITY
if (timer_sec.available()) // Gdy przekroczono time odczytu ADC, uruchom odczyty
{
}
}
// FUNKCJE
void helper_sortowanie(int a[], int size) {
for ( int i = 0 ; i < ( size - 1 ) ; i++)
{
for ( int o = ( i + 1 ) ; o < size ; o++ )
{
if(a[o] > a[o+1])
{
int t = a[o];
a[o] = a[o+1];
a[o+1] = t;
}
}
}
}
float read_ADC(int pin, int ilosc_odczytow, bool odrzuc_brzegowe) {
int odczyty_ADC[ilosc_odczytow];
float srednia = 0.0;
// odczytanie n wynikow
for (int i = 0; i < ilosc_odczytow; i = i + 1)
{
odczyty_ADC[i] = analogRead(pin);
}
if (odrzuc_brzegowe == 1 && ilosc_odczytow > 2)
{
// posortowanie
helper_sortowanie(odczyty_ADC, ilosc_odczytow);
// odrzucenie skrajnych i usrednienie
for (int i = 1; i < ilosc_odczytow - 1; i = i + 1)
{
srednia = srednia + odczyty_ADC[i];
}
return srednia / (ilosc_odczytow - 2);
}
else
{
// przelicz srednia dla wszystkich
for (int i = 0; i < ilosc_odczytow; i = i + 1)
{
srednia = srednia + odczyty_ADC[i];
}
return srednia / ilosc_odczytow;
}
return 0;
}
void ros_set_joint_min_position( const std_msgs::Float64& cmd_msg) {
min_position = cmd_msg.data;
}
void ros_set_joint_max_position( const std_msgs::Float64& cmd_msg) {
max_position = cmd_msg.data;
}
void ros_set_temp_limit( const std_msgs::Float64& cmd_msg) {
max_temp = cmd_msg.data;
}
void ros_set_current_limit( const std_msgs::Float64& cmd_msg) {
max_current = cmd_msg.data;
}
void ros_set_joint_position( const std_msgs::Float64& cmd_msg) {
// analogWrite(pin_PWM, 2550);
// digitalWrite(pin_DCL, HIGH);
// digitalWrite(pin_DCR, LOW);
if (cmd_msg.data > 0) {
// pwmWrite(pin_PWM, cmd_msg.data);
analogWrite(pin_PWM, cmd_msg.data);
digitalWrite(pin_DCL, HIGH);
digitalWrite(pin_DCR, LOW);
} else if (cmd_msg.data < 0) {
// pwmWrite(pin_PWM, cmd_msg.data * -1);
analogWrite(pin_PWM, cmd_msg.data * -1);
digitalWrite(pin_DCL, LOW);
digitalWrite(pin_DCR, HIGH);
} else {
// pwmWrite(pin_PWM, 0);
analogWrite(pin_PWM, 0);
digitalWrite(pin_DCL, HIGH);
digitalWrite(pin_DCR, HIGH);
}
// adc_msg.data = cmd_msg.data;
// publish_en.publish(&adc_msg);
// nh.spinOnce();
}
Asked by pawlass on 2018-09-21 03:51:06 UTC
Answers
You can write your own hw_interface program in either c++ or python where u can add the libraries to read the hardware information or send the motor commands, for eg. u can pigpio or wiring pi library to interface your hardware to your ros controller. Than u can easily use ros control to control any robot you want. Only part which should be modified is the hardware interface where you add the external libraries generally to communicate the hardware(actuator, encoder) .
Asked by dinesh on 2018-09-23 00:56:00 UTC
Comments
hw_interface
Asked by dinesh on 2018-09-21 03:53:29 UTC
@dinesh, I've turned your answer into a comment. It was too short and as-is, not of much help to the OP.
ros_control
cannot be used directly on Arduinos, so if you can provide a little more detail on the setup that you have in mind, that would be good.Asked by gvdhoorn on 2018-09-21 05:43:22 UTC