Comments (15)
Hello, @migsdigs is there a possibility of using directly micro-ROS module for ESP-IDF? I guess that you will have a better development experience with micro-ROS.
If not possible, could you share your code so we can take a look?
from micro_ros_platformio.
Hello @pablogs9, I hope you are well. I have been doing the majority of my project using platformio and I am unfamiliar with the ESP-IDF, but If this will be the only option to get micro-ROS working nicely on my board, for sure I will use it. I also see that the ESP-IDF does not have support for the older espressif platforms, which I require.
The code is at this link: https://github.com/migsdigs/Hiwonder_xArm_ESP32/blob/main/Hiwonder_xArm_ROS2/src/main.cpp. The uncommented code is just the example from the publisher example. You can see in https://github.com/migsdigs/Hiwonder_xArm_ESP32/blob/main/Hiwonder_xArm_ROS2/platformio.ini how much environment is configured.
My feeling is that the issue is something to do with the way ros interfaces with the timers on the board itself, and maybe there is some slight difference in the timer or clock configuration between the two different boards.
from micro_ros_platformio.
Ok, so let's focus on this code running in your current toolchain/platform: https://github.com/migsdigs/Hiwonder_xArm_ESP32/blob/main/Hiwonder_xArm_ROS2/src/main.cpp
- Does it work if you publish directly in the
loop()
function? - Does it freeze or if you have a printf inside the loop it just runs and skips the timer trigger?
- Does it enter in the timer callback?
- Could you provide the micro-ROS Agent output with the flag
-v6
?
from micro_ros_platformio.
- Yes, it does publish directly in the
loop()
function. - It does not enter the timer callback, I have done some debugging with this and also used some flag to see if it does enter it. It does not.
- The micro-ROS agent output is in the attached txt file.
from micro_ros_platformio.
Does it enters the timer if you remove the delay(100)
in the loop()
?
If not I guess that you shall check that this function is working correctly:
Maybe printing its return value to check that you are having a monotonic clock.
from micro_ros_platformio.
I removed the delay(100)
from the loop.
It now enters the callback, but it does it somewhat randomly (definitely not 1 second periodically), and I see it publish when I echo the topic, but yeah somewhat randomly (around 2-4 seconds).
Also tried making the delay in the loop smaller, for example delay(10)
, then it does not enter the callback, as before.
You still think I should look into that function?
Thanks for the help thus far :)
from micro_ros_platformio.
Sure, take a look at that function we have found some platforms where micros() or millis() are not working properly.
If not, it might be a transport issue.
Btw if you test a smaller delay, let say 1/10 of you spin rate. How does it behaves?
from micro_ros_platformio.
Alright, thanks. I will take a look.
On your last point, i tried a smaller delay (10 ms), and then it didn't enter the callback either.
from micro_ros_platformio.
Does it enters the timer if you remove the
delay(100)
in theloop()
?If not I guess that you shall check that this function is working correctly:
Maybe printing its return value to check that you are having a monotonic clock.
On a bit of a separate note. Is there a way of printing to the ROS agent terminal? Whenever I printf() or Serial.println() in platformio I have random outputs in the terminal even though my baud and monitor rates are consistent. This also only happens when I am running something else over the serial line (like communicating between my pc and my esp32).
Thanks again
from micro_ros_platformio.
You are using the Serial device in your platform as the micro-ROS communication device.
You cannot use it to print into the terminal or you will generate interferences with the micro-ROS wire protocol
You can:
- Try to create a new Serial device on another port.
- Don't call any micro-ROS code, just print normally the output of this method in an independent application with no micro-ROS
from micro_ros_platformio.
To try make my life simpler I tried using a 'native' esp32 timer using functions from esp32-hal-timer.c
to publish my messages. While the timer does indeed work, which I can confirm by my periodically lighting LED on IO pin 2. I am however having some issues when I add the publish line to my timer callback, being that 1. it does not publish every second, rather every +-10 seconds (while the LED continues to blink every second) and 2. the ESP proceeds to reset and run its setup() function between every publish.
Since the script for this is rather long, the basic code is as follows:
// includes
...
rosidl_runtime_c__String__Sequence name__string_sequence;
// Array to populate JointState message for Servo positions
double pos[6] = {0, 0, 0, 0, 0, 0}; // servo positions
double effort_array[] = {0, 0, 0, 0, 0, 0}; // effort array (just needed to populate message component)
double vel[] = {0, 0, 0, 0, 0, 0}; // velocity array " "
// Timer settings
static const uint16_t timer_divider = 80;
static const uint64_t timer_max_count = 1000000;
static hw_timer_t *timer = NULL;
rcl_node_t node_hiwonder; // Node object
// Publisher and Subscriber objects
rcl_publisher_t publisher;
rclc_support_t support;
rcl_allocator_t allocator;
rclc_executor_t executor_servo_pos_publish;
// ROS Error Handling
#define RCCHECK(fn) { rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){error_loop();}}
...
// ROS messages
sensor_msgs__msg__JointState servo_position_array_msg;
// timer callback / Interupt
void IRAM_ATTR onTimer() {
// Toggle LED
int pin_state = digitalRead(LED_BUILTIN);
digitalWrite(LED_BUILTIN, !pin_state);
pos[0] = servo1.pos_read();
pos[1] = servo2.pos_read();
pos[2] = servo3.pos_read();
pos[3] = servo4.pos_read();
pos[4] = servo5.pos_read();
pos[5] = servo6.pos_read();
// Update servo_position_array_msg
servo_position_array_msg.position.data = pos;
servo_position_array_msg.effort.data = effort_array;
servo_position_array_msg.velocity.data = vel;
servo_position_array_msg.header.stamp.sec = (uint16_t)(rmw_uros_epoch_millis()/1000); // timestamp
servo_position_array_msg.header.stamp.nanosec = (uint32_t)rmw_uros_epoch_nanos(); // timestamp
// Publishes
RCSOFTCHECK(rcl_publish(&publisher_servo_pos, &servo_position_array_msg, NULL));
}
void setup() {
Serial.begin(115200);
set_microros_serial_transports(Serial);
delay(2000);
// Timer settings
// Create and start timer (num, divider, countUp)
timer = timerBegin(0, timer_divider, true);
// Provide ISR to timer (timer, function, edge)
timerAttachInterrupt(timer, &onTimer, true);
// At what count should ISR trigger (timer, count, autoreload)
timerAlarmWrite(timer, timer_max_count, true);
// Allow ISR to trigger
timerAlarmEnable(timer);
// Servo settings etc...
Serial.println("Beginning Servo Example");
servoBus.beginOnePinMode(&Serial2,33);
servoBus.debug(true);
servoBus.retry=1;
...
// ros setup
allocator = rcl_get_default_allocator(); // Initialize micro-ROS allocator
RCCHECK(rclc_support_init(&support, 0, NULL, &allocator)); // Initialize support options
// create node
RCCHECK(rclc_node_init_default(&node_hiwonder, "Hiwonder_xArm_node", "", &support));
// Servo position publisher (publishes at a rate of 100 Hz)
RCCHECK(rclc_publisher_init_default(
&publisher_servo_pos,
&node_hiwonder,
ROSIDL_GET_MSG_TYPE_SUPPORT(sensor_msgs, msg, JointState),
"servo_pos_publisher"));
// message initialisation
bool success = rosidl_runtime_c__String__Sequence__init(&name__string_sequence, 6);
servo_position_array_msg.name = name__string_sequence;
success = rosidl_runtime_c__String__assignn(&servo_position_array_msg.name.data[0], "Servo1", 6);
success = rosidl_runtime_c__String__assignn(&servo_position_array_msg.name.data[1], "Servo2", 6);
success = rosidl_runtime_c__String__assignn(&servo_position_array_msg.name.data[2], "Servo3", 6);
success = rosidl_runtime_c__String__assignn(&servo_position_array_msg.name.data[3], "Servo4", 6);
success = rosidl_runtime_c__String__assignn(&servo_position_array_msg.name.data[4], "Servo5", 6);
success = rosidl_runtime_c__String__assignn(&servo_position_array_msg.name.data[5], "Servo6", 6);
...
// init executors
RCCHECK(rclc_executor_init(&executor_servo_pos_publish, &support.context, 1, &allocator)); // executor for publishing servo pos.
}
void loop() {
delay(20);
}
Have you perhaps experienced something similar before? And is the issue of the ESP resetting perhaps something memory related (memory leak or exceeding flash)?
I would greatly appreciate any feedback.
from micro_ros_platformio.
I'm not sure that running micro-ROS code in an ISR is a good idea. Is this timer an ISR?
from micro_ros_platformio.
I'm not sure that running micro-ROS code in an ISR is a good idea. Is this timer an ISR?
It is. And judging by my troubles, I am inclined to agree with you.
from micro_ros_platformio.
Not sure if running the whole rcl_publish procedure inside an ISR. It takes some time, is very depth in stack and it is probable that makes other system calls.
from micro_ros_platformio.
Not sure if running the whole rcl_publish procedure inside an ISR. It takes some time, is very depth in stack and it is probable that makes other system calls.
Alright, thanks for the info!
from micro_ros_platformio.
Related Issues (20)
- Feature request Wifi transport for RP2040 W HOT 9
- rosidl_runtime_cppConfig.cmake missing error HOT 2
- Modules won't compile with colcon build HOT 1
- ament_cmake clone failed when compiling for esp32-dev HOT 19
- MicroROS spin_some() blocks the functionality of the Adafruit bno08x library HOT 2
- Crashing when connected to Agent over UDP HOT 3
- Windows 11 VSCode "'.' is not recognized as an internal or external command" when adding library to lib_deps in platformio.ini HOT 3
- Micro-ROS parameter server not reporting correct parameter values to host on initial connection HOT 2
- Arduino Wire.h I2C custom transport on Pi Pico is causing a crash
- Same message is received continuously. HOT 6
- Publishing to a subscriber causes rclc_executor_spin_some to return a fail code. HOT 2
- Wrong UNIX time from rmw_uros_sync_session HOT 1
- Can't get topics to show on ROS2 Humble HOT 1
- ESP32-EVB support
- Failer build the firmware HOT 5
- No nodes or topics visible using ESP32 and WiFi transport HOT 31
- [Feature request] custom task kill micro-ros-agent and upload to board HOT 1
- Why use "-DRMW_UXRCE_TRANSPORT=custom" in metas? rmw_microros discovery.c won't build. HOT 1
- tf2_msgs not in micro_ros_platformio HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from micro_ros_platformio.