beagleboard / librobotcontrol

Robotics Focused library for embedded Linux computers. Mirror of https://git.beagleboard.org/beagleboard/librobotcontrol
https://beagleboard.org/librobotcontrol
MIT License
196 stars 158 forks source link

Multiple "Servo" PWM Outputs Simultaneously #110

Closed TheMadHatt3r closed 6 years ago

TheMadHatt3r commented 6 years ago

Hello,

Not sure if this is a real "issue" but it seems like the servo library will generate nice pulses for a single channel. As soon as I try to drive multiple channels, everything above channel one just chatter.

I figured maybe a single timer etc. is used for the pulse timing, so I added delays between calls to rc_servo_send_pulse_us. My pulses are standard RC 1-2ms. Even adding a 4ms delay between issuing 2ms pulses to 4 separate channels one after another, the problem still exists, although it is marginally better.

I saw issue #60, but it was unclear if there is a solution to this other then flashing new pru code? It seems like there would be a better way to implement the servo library that does not need continuous calling in a Linux user space program to generate PWM pulses.

Any advice to drive 4 RC servos at once? Should I be able to call rc_servo_send_pulse_us for multiple servo channels one after another? Or could it be something to do with using the newest Kernel 4.14?

model:[TI_AM335x_BeagleBone_Black_RoboticsCape]
dogtag:[BeagleBoard.org Debian Image 2018-05-27]
bootloader:[eMMC-(default)]:[/dev/mmcblk1]:[U-Boot 2018.03-00002-gac9cce7c6a]:[location: dd MBR]
kernel:[4.14.40-ti-r50]
nodejs:[v6.14.2]
device-tree-override:[dtb=am335x-boneblack-roboticscape.dtb]
uboot_overlay_options:[enable_uboot_overlays=1]
uboot_overlay_options:[uboot_overlay_pru=/lib/firmware/AM335X-PRU-RPROC-4-14-TI-00A0.dtbo]
pkg:[bb-cape-overlays]:[4.4.20180424.0-0rcnee0~stretch+20180424]
pkg:[bb-wl18xx-firmware]:[1.20180517-0rcnee0~stretch+20180517]
pkg:[firmware-ti-connectivity]:[20170823-1rcnee1~stretch+20180328]
StrawsonDesign commented 6 years ago

putting delays between sending pulses will probably cause erratic behavior as the overall update rate will be slowed to all servos. It's fine to send all 4 consecutively, this is what the library does when asked to send to all 8 at once. The channels should not effect each other at all, the PRU times each one individually.

Can you provide example code that demonstrates this? I haven't observed this behavior in any of my robots.

TheMadHatt3r commented 6 years ago

Here is a summary of my code, I have a loop timer that I know loop execution is dominated by the 250us time delay, and I have tested the PWM function is only running once every 20ms (50Hz)... There is an array motorPwms[] that contains my PWM times in us ranging from 1000 to 2000.

For testing I'm driving a small servo, with a 12V DC supply to the board. The servo in CH1 works great, CH2 it half works, and anything above that is just random bouncing. I have a oscilloscope but have not probed the signals yet.

while (true){
  ...
  ...
  //Basically while(true) adds up running time and triggers this once per 1/50Hz (20ms)
  if ( lastPwmTime_ms > (1000.0/PWM_FREQ) ){
    lastPwmTime_ms = 0;
    for (int i=1; i<5; i++){
      rc_servo_send_pulse_us(i-1, motorPwms[i-1]);
      // I have tried adding the delay below, if helps somewhat.
      //std::this_thread::sleep_for(std::chrono::microseconds(2200));
      }
  }
  ...
  ...
std::this_thread::sleep_for(std::chrono::microseconds(250));
}
TheMadHatt3r commented 6 years ago

I don't know why I did not think to do this earlier, but running the sudo rc_test_servos -f 50 -s 1 program performs as expected on all channels, so i guess there must be something with how I am using it in my code. I'll have to investigate further.

I'll try stripping my program of everything.

TheMadHatt3r commented 6 years ago

You can close this, I realized that somewhere between a windows UI and my c++ software, I was sending a rc_servo_send_pulse_us(0, 1500); That was trying to set all channels to neutral while I was also looping through channels 1-4...

Interestingly enough, channel 1 still works fine, and as you move down the line, it affects it more. Must be how the code in the pru is setup.