chrisl8 / ArloBot

ROS Package for a Parallax ArloBot Robot
https://log.voidshipephemeral.space/Arlobot/ArloBot+Build+Index
MIT License
39 stars 27 forks source link

Add Docking ability to charge robot when power is low #198

Closed chrisl8 closed 9 months ago

chrisl8 commented 2 years ago

Similar to how most robot vacuums can dock themselves and recharge.

Consider using this code: https://github.com/wennycooper/mybot_autodocking/

chrisl8 commented 2 years ago

As an initial test do this on the robot:

Setup

source ~/catkin_ws/devel/setup.bash
cd ~/catkin_ws/src
git clone https://github.com/wennycooper/mybot_autodocking.git
cd ~/catkin_ws
rosdep update
rosdep install -q -y -r --from-paths src --ignore-src
catkin_make

That should build and install the code.

Testing

Now, in a terminal window, on the robot run start-robot.sh OR start ROS from the web Interface.

Once it is going, in another terminal run:

source ~/catkin_ws/devel/setup.bash
rosrun mybot_autodocking mybot_autodocking

It should start with no output and just stay that way, I think.

In another window, run:

source ~/catkin_ws/devel/setup.bash
rostopic echo /irValue

Is there any output? If so, can you tell me what it is? If you "bring up" or "turn on" your IR device, does it that change things?

This is where I'm needing help, because I'm not sure what the output should look like.

Finally try this one:

rostopic echo /cmd_vel

and again. does it have any output when then IR system is operating?

TCIII commented 2 years ago

@chrisl8,

I will give it a shot this weekend.

I assume that I should have a functioning version of Cooper's 'IR_receiver_rosserial_ircode.ino' code on the IR Receiver Arduino Uno R3 that will output irCode.x = flag2; irCode.y = flag3; in the ROS serial format when the IR Transmitter beam is detected?

How does Cooper's ROS code know which input device to look at for the output of the Arduino Uno R3 ROS serial output?

Can the Arlobot chassis be stationary (on blocks) with the IR Receiver facing the IR Transmitter at some arbitrary distance since this is just a IR Receiver beam detection test?

Regards, TCIII

chrisl8 commented 2 years ago

@TCIII

When you run the rosrun mybot_autodocking mybot_autodocking I suggest having the robot on blocks, because it will probably start trying to move. I could be wrong, but that is the idea.

Also be aware that it will probably lock out all other input to the robot. I will have to add the setup to "mix" the input into the other sources, OR you will need to create some automation to only start the autodocking when you are ready to dock. We can work that out later.

You will want to watch the output of rostopic echo /cmd-vel and rostopic echo /irValue and if there IS output, then move the robot or IR sender to see if it appears to change the output. Honestly, if you get anything on rostopic echo /irValue that will be a successful first test.

I don't actually know how the Arduino talks to the ROS code or how it knows which input device to use. In fact, when I look into the code here I don't even see anything that is talking to other code: https://github.com/wennycooper/mybot_autodocking/tree/master/src

Both .cpp files seem to have code to send twist commands to ROS, and they subscribe to an /irValue topic, but what is publishing messages to the /irValue topic?

Maybe the Arduino code itself is doing that? If the Arduino is somehow able to publish right into the ROS topics running on the host, that would make sense. I didn't know that this was possible, but I've never tried either.

Also, I could be wrong about running rosrun mybot_autodocking mybot_autodocking

You might need to run this instead: rosrun mybot_autodocking_irCode mybot_autodocking_irCode

I guess try each or both to see what happens?

Make sure your Arduino is plugged in when you try it.

If nothing works, we'll have to do more debugging. I do have an Arduino, so I could probably test that code too, even without the IR hardware.

Let me know what you find.

TCIII commented 2 years ago

@chrisl8,

Thanks for the quick response, much appreciated.

I will integrate your detailed update into the testing.

Take a look at this 'IrRanger.pde' code that transmits an ir range using rosserial and is somewhat similar to Cooper's 'IR_receiver_rosserial_ircode.ino' code.

All of the required rosserial commands in the 'IrRanger.pde' code also appear in ''IR_receiver_rosserial_ircode.ino' code so the structure of the 'IR_receiver_rosserial_ircode.ino' code seems to be sound.

As you have indicated, how 'mybot_autodocking_irCode.cpp' or mybot_autodocking.cpp code accesses the output of the 'IR_receiver_rosserial_ircode.ino' code on the Arduino Uno R3 is not well understood at the moment.

This rosserial Package Summary may shed some light on how the ROS-side interfaces with the Arduino.

Also, after analyzing 'mybot_autodocking_irCode.cpp', it appears that Cooper's robot backed into the docking station as 'cmd->linear.x = -0.08;' is a negative value once the docking station has been found and the robot is aligned to the charging contacts.

I am attaching Cooper's Autodocking Guide that explains how he envisioned the autodocking process.

Regards, TCIII Autodocking Guide.zip

TCIII commented 2 years ago

@chrisl8,

I have posted a question on ROS Answers as to how Cooper's 'mybot_autodocking_irCode.cpp' code identifies the USB port and baud rate of the rosserial-enabled Arduino that is transmitting the IR Receiver beam detection data. I really have the feeling that Copper's 'mybot_autodocking_irCode.cpp' was a one-off experiment designed to run on a laptop where the Arduino Uno R3 was the only USB input and therefore the node did not have to search for the Arduino's port.

I don't think that our experiment will succeed until we understand how Cooper's 'mybot_autodocking_irCode.cpp' code detects the rosserial-enable Arduino.

Regards, TCIII

chrisl8 commented 2 years ago

@TCIII

Have you tried it yet? Did you upload code to the Arduino? If so, what code did you use? I haven't looked at the Arduino code myself, so I don't know how it works. If you send me a link to the .ino file you used, I could give some insight on how it appears to work.

It seems premature to me to call it a failure if you haven't tried it yet.

EDIT: Looking over both of your posts, I think I've probably failed to absorb everything you were trying to say. I apologize for that. I'm still not clear on whether you connected the Arudino to the robot's computer yet and tried it though. My guess is that the Arduino is able to connect to ROS somehow, but I could be making stuff up.

EDIT 2: Looking at https://wiki.ros.org/rosserial, it sounds like maybe there has to also be a "ROS Side" program running to capture the output from a device, like the Arduino, running ROS Serial? If so, that may be a missing piece that we have to start up also. This is why this project is incomplete, as he should have a .launch file that does this for us, as well as included it in the dependencies in the make file. Anyway, it is doable. I will probably have to get out an Arudino though and put the code on it to try it, as I have never used ROS Serial before.

TCIII commented 2 years ago

@chrisl8,

No, I have not tried the code per your instructions because I see no way that Cooper's 'mybot_autodocking_irCode.cpp' is going to be able to distinguish and identify the IR Receiver Arduino from the other USB components attached to the Rpi 4B.

I have not been able to find one example that uses a ROS-side node code that communicates with an Arduino. All of the examples use 'rosrun rosserial_python serial_node.py /dev/tty<USB# or ACM#>' from the CLI.

Here is what I used to view the Arduino IR Receiver output with the Arduino IDE Terminal:

`#include

// #define PIN_IR 3

define PIN_DETECT2 (2)

define PIN_DETECT3 (3)

// #define PIN_STATUS 13

unsigned int flag2, flag3; // IRsend irsend; void setup() {

Serial.begin(57600); pinMode(PIN_DETECT2, INPUT); pinMode(PIN_DETECT3, INPUT); // pinMode(PIN_STATUS, OUTPUT); // irsend.enableIROut(38); // irsend.mark(0); }

void loop() { flag2 = 0; flag3 = 0; if (digitalRead PIN_DETECT2 == LOW) flag2=1;{ }

if (digitalRead PIN_DETECT3 == LOW) flag3=1;{ }

if (flag2 && flag3) { Serial.println("Pin2: True, Pin3: True"); } if (flag2 && !flag3) { Serial.println("Pin2: True, Pin3: False"); } if (!flag2 && flag3) { Serial.println("Pin2: False, Pin3: True"); }

} ` Here is the same Arduino code with Cooper's ros commands added. It compiled correctly once I modified the rosserial_arduino_library as I mentioned in a post above:

`#include

include <geometry_msgs/Vector3.h>

//#include

// #define PIN_IR 3

define PIN_DETECT2 (2)

define PIN_DETECT3 (3)

// #define PIN_STATUS 13

unsigned int flag2, flag3;

ros::NodeHandle nh; geometry_msgs::Vector3 irCode; ros::Publisher pub("irCode", &irCode);

// IRsend irsend; void setup() { nh.initNode(); nh.advertise(pub);

Serial.begin(57600);

pinMode(PIN_DETECT2, INPUT); pinMode(PIN_DETECT3, INPUT); // pinMode(PIN_STATUS, OUTPUT); // irsend.enableIROut(38); // irsend.mark(0); }

void loop() { flag2 = 0; flag3 = 0; if (digitalRead PIN_DETECT2 == LOW) flag2 = 1; { }

if (digitalRead PIN_DETECT3 == LOW) flag3 = 1; { }

/ if (flag2 && flag3) { Serial.println("Pin2: True, Pin3: True"); } if (flag2 && !flag3) { Serial.println("Pin2: True, Pin3: False"); } if (!flag2 && flag3) { Serial.println("Pin2: False, Pin3: True"); } /

irCode.x = flag2; irCode.y = flag3; pub.publish(&irCode);

nh.spinOnce();

// digitalWrite(PIN_STATUS, !digitalRead(PIN_DETECT));

} ` The above code needs to be cleaned up to remove the unnecessary commented lines.

Comments?

TCIII

chrisl8 commented 2 years ago

@TCIII My guess is that you probably need to do everything I mentioned above, and also run:

rosrun rosserial_python serial_node.py /dev/tty<USB# or ACM#>

which will provide the bridge between the Arduino and ROS, and then you would see data on the /irValue topic.

I don't see "irValue" in the cod you pasted, so it may also be necesary to pass the "topic" to serial_node.py somehow? Unless the .ino file provided by the project already encodes that somehow?

TCIII commented 2 years ago

@chrisl8,

"irValue" is called "irCode" in the Arduino .ino code above:

`geometry_msgs::Vector3 irCode; ros::Publisher pub("irCode", &irCode); irCode.x = flag2; irCode.y = flag3; pub.publish(&irCode);`

From Cooper's 'mybot_autodocking_irCode.cpp':

irValue_sub = nh.subscribe("/irCode", 10, irValueCallback);

`void irValueCallback(const geometry_msgs::Vector3 &vector3)`
`vec3.x = vector3.x;
 vec3.y = vector3.y;`

Apparently the Vector3.h messages are the link between the Arduino irCode and the irValue values?

I believe that Cooper's 'mybot_autodocking_irCode.cpp' is the ROS-side node that you are referring to, but I don't see where he establishes communication (USB port/baud rate) with the Arduino. Unless it is done with #include < 'ros/ros.h'>?

Cooper's 'mybot_autodocking_irCode.cpp' is definitely acting as a 'subscriber' . The giveaway is the:

irValue_sub = nh.subscribe("/irCode", 10, irValueCallback);

void irValueCallback(const geometry_msgs::Vector3 &vector3)

typedef void(ObjT::*CallbackT)(const MReq&, MRes&);

Regards, TCIII

chrisl8 commented 2 years ago

@TCIII

No harm in just trying things either. Run the code, see what happens.

It sounds like I will have to put some code on an Arduino to fully know how to make it work. I might get to that this weekend or I might not.

This kind of complex setup process, long string of dependencies, and lots of half-documented solutions is why I made this repository to begin with. ROS is great, but it is not full of people who like to document things or maintain fully functioning systems. 😄

TCIII commented 2 years ago

@chrisl8,

I plugged in the Adafruit Metro 328 to the ArloBot USB Hub and ran:

cd /dev
/dev ls

To determine the IR Receiver Metro 328 USB port number which is USB0 The RPLIDAR is USB1 The PAB is USB2 The NeoPixel Arduino Uno is ACM0

I have the IR Transmitter pointed at the IR Receiver Assembly mounted on the ArloBot and the IR Receiver LEDs are indicating reception of the IR Transmitter beam.

I then completed the steps in "Setup" and received the following:

[100%] Built target mybot_autodocking_irCode [100%] Built target mybot_autodocking

I then ran the following in separate terminals:

start-robot.sh

source ~/catkin_ws/devel/setup.bash rosrun mybot_autodocking mybot_autodocking

source ~/catkin_ws/devel/setup.bash rostopic echo /irValue

No output with or w/o IR beam

However the Right Wheel turned forward and the Left wheel turned backward with or w/o the IR beam.

rostopic echo /cmd_vel output with and w/o the IR beam:

linear: x: 0.0 y: 0.0 z: 0.0 angular: x: 0.0 y: 0.0 z: 0.15

When I ran rosrun rosserial_python serial_node.py /dev/ttyUSB0 to see if I could see the irValue, the CLI came back with 'rosserial_python' not installed.

How should I install rosserial_python? It appears it can be installed from source or from apt-get install: sudo apt-get install ros-noetic-rosserial-python

Comments?

TCIII

TCIII commented 2 years ago

@chrisl8,

I have run rosrun mybot_autodocking mybot_autodocking_irCode and received the following on the CLI until I hit ^C:

thomas@thomas-desktop:~$ rosrun mybot_autodocking mybot_autodocking_irCode x=0.000000, y=0.000000 x=0.000000, y=0.000000

I had to change rosrun mybot_autodocking_irCode mybot_autodocking_irCode to rosrun mybot_autodocking mybot_autodocking_irCode because mybot_autodocking_irCode is in the 'mybot_autodocking' directory. The 'mybot_autodocking_irCode' directory does not exist.

Running the following:

source ~/catkin_ws/devel/setup.bash rostopic echo /irValue

Yielded the following with and w/o the IR beam: WARNING: topic [/irValue] does not appear to be published yet

Running the following:

source ~/catkin_ws/devel/setup.bash rostopic echo /cmd_vel

Yielded this output with and w/o the IR beam:

linear: x: 0.0 y: 0.0 z: 0.0 angular: x: 0.0 y: 0.0 z: 0.1

Looks like we are making some progress using rosrun mybot_autodocking mybot_autodocking_irCode, but the mybot_autodocking_irCode node is not getting input from the Metro 328 IR Receiver. Therefore I need advice on installing rosserial_python.

Comments?

TCIII

TCIII commented 2 years ago

@chrisl8,

You are right about Cooper's ROS code being incomplete. Here is the ROS Answers response:

"On the host running rosserial, ROS is not responsible for "finding" the linux /dev/[somehing] device. The author of the ROS launch file must create entries on the ros-parameter-server specifying a linux device name and a baudrate.

For USB, creating the linux device in /dev is typically done with a udev rule. You must install this rule before you insert the usb device and before the ROS launch file is executed. This new udev rule will be triggered when your specific USB-device is inserted, and then udev will create a fixed linux /dev name that you specify in the rule e.g. /dev/arduino

For this to work, the name in the udev rule has to exactly match the device name you specify in your ROS launch file."

I know that the IR Receiver Metro 328 is on USB0 and its baud rate is set at the default 57600.

Should I use udevadm to determine the IR Receiver Metro 328 info?

Regards, TCIII

TCIII commented 2 years ago

@chrisl8,

Will you be able to do the following this week so that I can continue to validate the robot docking software:

1) Create a find_IR_Receiver.sh script to identify the USB port that the Arduino IR Receiver is connected to. 2) Create a ROS launch file for the ROS node mybot_autodocking mybot_autodocking_irCode that specifies the Arduino IR Receiver USB port and any other support modules that are required.

As far as item one goes, I assume that you will add a .arduinoUniqueString and a .arduinoStringLocation to a "useArduinoForIRReceiver": true, in the "personalDataForBehavior.json" file to be determined by running udevadm info --query=property --name /dev/ttyUSB0 where the Arduino IR Receiver is on USB0?

Regards, TCIII

TCIII commented 2 years ago

@chrisl8,

I would appreciate some input here as I would like to move this project along to completion.

Regards, TCIII

chrisl8 commented 2 years ago

@TCIII

Did you install ros-noetic-rosserial-python yet?

TCIII commented 2 years ago

@chrisl8,

Thanks for the response, much appreciated.

Not yet as I was waiting for your feedback which you have given.

Once I install ros-noetic-rosserial-python do you want me to run rosrun mybot_autodocking mybot_autodocking_irCode and try running source ~/catkin_ws/devel/setup.bash followed by rostopic echo /irValue and then try running source ~/catkin_ws/devel/setup.bash followed by rostopic echo /cmd_vel?

Regards, TCIII

chrisl8 commented 2 years ago

@TCIII

Yes, and then in addition run rosrun rosserial_python serial_node.py /dev/ttyUSB0 (or whatever the device name is for the IR controller that is connected)

TCIII commented 2 years ago

@chrisl8,

Unfortunately sudo apt-get install ros-noetic-rosserial-python failed to install:

Get:1 http://packages.ros.org/ros/ubuntu focal/main arm64 ros-noetic-rosserial-msgs arm64 0.9.2-1focal.20210424.032443 [23.8 kB]
Err:2 http://packages.ros.org/ros/ubuntu focal/main arm64 ros-noetic-rosserial-python arm64 0.9.2-1focal.20210922.181500
  404  Not Found [IP: 140.211.166.134 80]
Fetched 23.8 kB in 1s (33.2 kB/s)
E: Failed to fetch http://packages.ros.org/ros/ubuntu/pool/main/r/ros-noetic-rosserial-python/ros-noetic-rosserial-python_0.9.2-1focal.20210922.181500_arm64.deb  404  Not Found [IP: 140.211.166.134 80]
E: Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?

TCIII

chrisl8 commented 2 years ago

@TCIII

You are either having network/Internet issues or there is some outage for the particular ROS mirror you hit.

You can try running these to confirm/update your package settings:

sudo apt update
sudo apt upgrade

and then try again. It could just be transient. packages.ros.org does sometimes go down or get overloaded.

TCIII commented 2 years ago

@chrisl8,

It will take a while as there are 291 packages to upgrade.

TCIII

TCIII commented 2 years ago

@chrisl8,

I found this sudo apt install -y ros-noetic-rosserial-python here. What do you think?

TCIII

TCIII commented 2 years ago

@chrisl8,

Running sudo apt install -y ros-noetic-rosserial-python worked after the update/upgrade finished.

TCIII

TCIII commented 2 years ago

@chrisl8,

Since the update/upgrade, find_camera.sh UVC cannot find the camera so start-robot.sh will not run.

Running fswebcam --verbose --device=/dev/video0 2>&1|grep cap.card gives:

src_v4l2_get_capability,89: cap.card: "Video Capture 5" whereas the camera used to be "UVC"

I will change "camera0name": from "UVC" to "Video Capture 5", in personalDataForBehavior.json.

Running find_camera.sh Video Capture 5 gives: /dev/video0

It is interesting what a update/upgrade will do to Ubuntu.

TCIII

TCIII commented 2 years ago

@chrisl8,

Made some progress:

Ran the following sequence in separate terminals:

start-robot.sh

source ~/catkin_ws/devel/setup.bash rosrun mybot_autodocking mybot_autodocking_irCode

source ~/catkin_ws/devel/setup.bash rosrun rosserial_python serial_node.py /dev/ttyUSB0

source ~/catkin_ws/devel/setup.bash rostopic echo /irValue

rosrun mybot_autodocking mybot_autodocking_irCode output when both IR Receivers were illuminated:

x=0.000000, y=0.000000 x=1.000000, y=1.000000 #the wheels were turning in reverse as expected from Cooper's 'mybot_autodocking_irCode.cpp' code. x=0.000000, y=0.000000

rosrun rosserial_python serial_node.py /dev/ttyUSB0 output:

[INFO] [1645563476.048943]: ROS Serial Python Node [INFO] [1645563476.066510]: Connecting to /dev/ttyUSB0 at 57600 baud [INFO] [1645563478.185020]: Requesting topics... [INFO] [1645563478.280282]: Note: publish buffer size is 280 bytes [INFO] [1645563478.284677]: Setup publisher on irCode [geometry_msgs/Vector3]

rostopic echo /irValue output:

WARNING: topic [/irValue] does not appear to be published yet

So it looks like there is a disconnect between /irValue in the .cpp code and /irCode in the Arduino ino.

"irValue" is called "irCode" in the Arduino .ino code:

geometry_msgs::Vector3 irCode; ros::Publisher pub("irCode", &irCode); irCode.x = flag2; irCode.y = flag3; pub.publish(&irCode);`

From Cooper's 'mybot_autodocking_irCode.cpp':

irValue_sub = nh.subscribe("/irCode", 10, irValueCallback);

void irValueCallback(const geometry_msgs::Vector3 &vector3) vec3.x = vector3.x; vec3.y = vector3.y;

Comments?

TCIII

chrisl8 commented 2 years ago

@TCIII

When all of this is running, what does the output of rostopic echo /irCode show?

EDIT: I think that you can entirely ignore /irValue, that was a red herring introduced by the other .cpp file, but the mybot_autodocking_irCode instance that you are running is listening to /irCode, which the Arduino is hopefully publishing to?

TCIII commented 2 years ago

@chrisl8,

Nice catch as I did not try rostopic echo /irCode. Apparently Cooper converted /irCode to irValue in mybot_autodocking_irCode.cpp:

ros::NodeHandle nh; cmd_vel_pub = nh.advertise<geometry_msgs::Twist>("/cmd_vel", 50); irValue_sub = nh.subscribe("/irCode", 10, irValueCallback);

Just about dinner time so I will have to take a break. Recharging the ArloBot batteries too.

TCIII

TCIII commented 2 years ago

@chrisl8,

I ran the setup code again and this time I ran rostopic echo /irCode.

When I had the IR beam illuminating both IR Receivers the output looked like this:

x: 1.0 y: 1.0 z: 0.0

When I had the IR beam illuminating the Right IR Receiver the output looked like this:

x: 0.0 y: 1.0 z: 0.0

When I had the IR beam illuminating the Left IR Receiver the output looked like this:

x: 1.0 y: 0.0 z: 0.0

When I had the IR beam illuminating both IR Receivers both wheels were turning backwards as the robot thinks it is now aligned to the dock and is trying to engage the dock. The wheels are turning backwards because Cooper's mybot_autodocking_irCode had the robot back into the dock:

if (foundDockingStation) { geometry_msgs::TwistPtr cmd(new geometry_msgs::Twist()); cmd->linear.x = -0.08; # Going in reverse cmd->angular.z = 0.1 * (vector3.x - vector3.y); if (vector3.x || vector3.y) cmd_vel_pub.publish(cmd);

However, pointing the beam at just one sensor does not seem to make the mybot_autodocking_irCode attempt to rotate in the other direction in order to illuminate both detectors with the beam.

Shouldn't this code snippet from mybot_autodocking_irCode cause the robot to search for the beam or does your code not understand angular.z :

if (!foundDockingStation && vec3.x == 0.0 && vec3.y == 0.0) { geometry_msgs::TwistPtr cmd(new geometry_msgs::Twist()); cmd->angular.z = 0.1; // const rotate until cmd->linear.x = 0.0; cmd_vel_pub.publish(cmd); } else { foundDockingStation = 1;

The mybot_autodocking_irCode code only prints printf("x=%f, y=%f\n", vec3.x, vec3.y); so we never see an angular "z" value.

I will perform more testing tomorrow morning.

Comments?

TCIII

TCIII commented 2 years ago

@chrisl8,

Observation: After testing last night I found that the Right wheel was turning much faster than the Left wheel when ArloBot was supposed to go in a straight line. I tried several software fixes to no avail. Finally I used an air can to blow any dust out of the Right wheel optical encoder and that cured the problem. It might be a good idea to blow the dust out of the wheel encoders periodically. This is another reason why hall effect motor encoders are superior to optical wheel encoders. Also motor encoders tend to have much higher resolution than wheel encoders. When I was having the Right wheel issue I ran bash <(wget -qO- --no-cache -o /dev/null https://raw.githubusercontent.com/chrisl8/ArloBot/noetic/setup-noetic.sh) to see if there was a software issue.

Now when I run rosrun rosserial_python serial_node.py /dev/ttyUSB0 I get this error message:

[INFO] [1645631340.221298]: ROS Serial Python Node [INFO] [1645631340.236635]: Connecting to /dev/ttyUSB0 at 57600 baud [INFO] [1645631342.352447]: Requesting topics... [ERROR] [1645631342.475269]: Mismatched protocol version in packet (b'\xbf'): lost sync or rosserial_python is from different ros release than the rosserial client [INFO] [1645631342.483907]: Protocol version of client is unrecognized, expected Rev 1 (rosserial 0.5+)

Did running <(wget -qO- --no-cache -o /dev/null https://raw.githubusercontent.com/chrisl8/ArloBot/noetic/setup-noetic.sh) mess up rosserial client?

Found out what the problem is. Running <(wget -qO- --no-cache -o /dev/null https://raw.githubusercontent.com/chrisl8/ArloBot/noetic/setup-noetic.sh) rearranged the USB port numbers. The Arduino IR Receiver is now USB1 instead of USB0.

Observations:

1) When both IR Receivers are illuminated the irCode.cpp thinks that it is aligned with the docking station and begins backing up into the station:

if (foundDockingStation) { geometry_msgs::TwistPtr cmd(new geometry_msgs::Twist()); cmd->linear.x = -0.08; # Going in reverse cmd->angular.z = 0.1 * (vector3.x - vector3.y); if (vector3.x || vector3.y) cmd_vel_pub.publish(cmd);

2) When I illuminate either the Right or the Left, but not both, what should the irCode.cpp do to get both IR Receivers illuminated: if (!foundDockingStation && vec3.x == 0.0 && vec3.y == 0.0) { geometry_msgs::TwistPtr cmd(new geometry_msgs::Twist()); cmd->angular.z = 0.1; // const rotate until cmd->linear.x = 0.0; cmd_vel_pub.publish(cmd); } else { foundDockingStation = 1;

If there is no illumination of either IR Receiver, then it should begin rotation based on if (!foundDockingStation && vec3.x == 0.0 && vec3.y == 0.0) {, but the wheels quit turning. Do you think that cmd->angular.z = 0.1; is too slow for ArloBot?

Comments?

TCIII

TCIII commented 2 years ago

@chrisl8,

Here is a detailed look at docking using Twist as in the irCode.cpp, but it uses odometry instead of movement generated by IR beam detection.

TCIII

TCIII commented 2 years ago

@chrisl8,

Here is a snippet describing Cooper's docking algorithm as far as IR beam response goes:

If only R0 got RC5(0x43) code, the robot should rotate in CCW. If only R1 got RC5(0x43) code, the robot should rotate in CW. If both R0 and R1 got RC5(0x43) code, the robot should move forward. If neither R0 nor R1 got RC5(0x43) code for a period of time, it should be treat as "lost docking station", and it should go back to the previous stop. Until the sensor limitSW is contact to the docking station. Then stop the base.

Note: In our project "got RC5(0x43) code" should be treated as R1 or R2 receivers have detected the IR beam.

Comments?

TCIII

chrisl8 commented 2 years ago

Unfortunately Linux will move your USB devices around a lot. They are liable to change any time you reboot, or if you run any command that resets the devices, and of course if you unplug anything and plug it back in. That is why I made scripts to use stable values to find the ports when running things. I can try to guide you through making such a script for your new device.

My testing causes my robot to just rotate constantly, which makes sense, as it is continuously in the state of "no IR signal received, rotate until it is found" since I have no input device. Does your robot not do that?

What is the output of rostopic echo /cmd_vel?

TCIII commented 2 years ago

@chrisl8,

I have not looked at rostopic echo /cmd_vel recently, but will give it a shot.

As I described above, with no IR beam detected (irCode x:0, y:0, and z:0) the wheels quit turning, while with both IR receivers illuminated (irCode x:1, y:1, and z:0) the wheels turn backward as the irCode.cpp tries to back into the docking station: cmd->linear.x = -0.08; # Going in reverse cmd->angular.z = 0.1 * (vector3.x - vector3.y);

With x and y equal 1, angular.z = 0 so only linear.x = -0..08 which is reverse.

Yes, I would be interested in writing such a script.

TCIII

TCIII commented 2 years ago

@chrisl8,

Here is what I see with rostopic echo /cmd_vel:

1) No beam at the start: Linear x:0 y:0 z:0 Angular x:0 y:0 z:0.1 The wheels try to rotate left

2) Both IR Receivers illuminated: Linear x:-0.08 # backing up to the docking station y:0 z:0 Angular x:0 y:0 z:0.0 # an occasional -0.1 will appear momentarily

3) Only the Left IR Receiver illuminated: Linear x:-0.08 # why isn't x = 0.0 y:0 z:0 Angular x:0 y:0 z:0.1

3) Only the Right IR Receiver illuminated: Linear x:-0.08 # why isn't x = 0.0 y:0 z:0 Angular x:0 y:0 z:-0.1

4) If both IR Receivers are being illuminated and then not illuminated: Linear x:0 y:0 z:0 Angular x:0 y:0 z:0 The irCode.cpp will not try and hunt for the IR beam like it did when there was no IR beam at startup.

Observations:

1) I don't understand when only one IR Receiver is illuminated in 2 and 3 why Linear x = -0.08 while Angular z = either 0.1 or -0.1 when Linear x should be 0.0 so that Angular z will drive the robot either right or left to illuminate both IR Receivers.

2) I don't understand why the irCode.cpp will hunt for the beam at startup ( the first (1) above), but will not hunt for the beam if the beam has been illuminating both IR Receivers and then is taken away (beam lost).

Comments?

TCIII

chrisl8 commented 2 years ago

First, it looks like everything is working! 🥳 Maybe not perfectly, but your hardware is working, the code functions, and ROS is receiving input, and the robot is acting on it!

  1. My assumption for why X is not set to 0.0 when one side sees the IR signal is that the developer's intention was for it to continue to move toward the dock while correcting the orientation, rather than stopping and rotating to correct every time it got off to one side. Since it sees the IR beam, it knows the goal is in sight, so it might as well move toward it, even while correcting the angle. Imagine the difference between a smooth wavy line as it approaches vs. a series of sharp zig-zags as it stops, corrects starts again, stops, corrects, starts again. My guess is that the specific values in the code may require tuning on your part to make it work best with your robot, with your dock, on your floor surface.

You can adjust the X value as you see fit at line 23 of mybot_autodocking_irCode.cpp although that is the only place X is set, so if you make it 0.0, it will never move toward the goal. More logic will need to be added to the code if you want it to set X to 0.0 when rotating, but higher when moving straight.

Remember that changes to cpp code will not affect code until you run catkin_make again like you did in the setup to rebuild the code. (That is one drawback of C++ code vs. Python code in ROS. The benefit is that C++ code in theory runs faster with less load on the CPU, although that is debatable with modern Python and CPUs.)

  1. If you look at the code in mybot_autodocking_irCode.cpp you can see that it sets an initial value of 0 for foundDockingStation in line 9, and then in line 54 sets it to 1, but it never sets it back to 0 ever.

So the code author assumed that once the IR beam was seen, it would remain seen until docked. This was either a very poor assumption or just one that worked for the author and not you.

It will take some updates to the mybot_autodocking_irCode.cpp code to change that behavior.

TCIII commented 2 years ago

@chrisl8,

Thanks for the analysis, much appreciated.

So I could change Linear x = -0.08 to Linear x = 0.08 to have the robot chassis move forward instead of backwards to dock and then use catkin_make to recompile the code?

To use Cooper's code there has to be an input to ROS that tells the docking code when the robot is docked so that Linear x = 0.0. He apparently used a limit switch to tell the ROS code when the robot had docked, but never integrated it into the irCode.cpp. What do you envision as the path forward now with the docking project? This could be useful for the "off the shelf" robot chassis that you have planned?

TCIII

TCIII commented 2 years ago

@chrisl8,

Can we work up a plan to integrate the docking code into the ArloBot/ROS software package and make it an option in the personalDataForBehavior.json file?

1) The forward looking PING will probably have to be ignored so that the robot does not attempt an Escape as it gets very close to the dock. 2) Integrate a limit switch into the PAB code so the docking codes knows when the robot is seated in the dock. 3) Come up with a charging sequence that charges both the battery and keeps the SBC and accessories running at the same time.

Comments?

TCIII commented 2 years ago

@chrisl8,

I changed the cmd->linear.x = -0.08; to cmd->linear.x = 0.08; and reran catkin_make. Now ArloBot moves forward when both IR Receivers are illuminated. I left the IR transmitter off at startup and ArloBot began a very slow CCW turn when looking from the front as it searched for the IR transmitter beam. I believe that you saw the same response when there was no IR transmitter beam at start up?

Thoughts about the docking station supplied voltage and current required to charge the battery and run the SBC at the same time: 1) Most three stage SLA battery chargers require around 16 vdc. My SBC and accessories stepdown voltage regulators can handle between 12-24 vdc so that won't be a problem. 2) The three SLA battery chargers I have charge at a 1 amp rate which means that the 1 amp current is split between the two SLA batteries. 3) I would estimate that the SBC and accessories (PAB/DHB-10/Arduinos/etc) are probably drawing around minimum current while docked so maybe figure around 3 amps. 4) Therefore the docking station should be capable of supplying 16 vdc and at least 5 amps through the docking contacts.

Comments?

TCIII

TCIII commented 2 years ago

@chrisl8,

Bump?

I have created a find_IR_Receiver.sh script by doing the following:

1) Identified the IR Receiver Arduino to be USB0 using /dev/tty 2) Used udevadm info /dev/ttyUSB0 to determine the Arduino ID_SERIAL: "Silicon_Labs_CP2104_USB_to_UART_Bridge_Controller_019990C9". The ID_MODEL cannot be used because it is the same for all Silicon_Labs_CP2104_USB_to_UART_Bridge_Controllers. 3) Modified find_RPLIDAR.sh by changing "CP2102_USB_to_UART_Bridge_Controller" ID_MODEL to "Silicon_Labs_CP2104_USB_to_UART_Bridge_Controller_019990C9" ID_SERIAL 4) Added find_IR_Receiver.sh to ~/catkin_ws/src/ArloBot/scripts 5) However, I have to use bash find_IR_Receiver.sh to get it to execute. How do I convert find_IR_Receiver.sh to execute from the CLI without using bash ?

The personalDataForBehavior.json file can be modified to include a "useIRReceiverforDocking" where the IR Receiver ID_SERIAL can be added and the find_IR_Receiver.sh modified such that it searches for STRING=$ and LOCATION=$ that are located in the personalDataForBehavior.json file?

TCIII

TCIII commented 2 years ago

@chrisl8,

Instead of using the limit switch, that Cooper proposed, to indicate when the robot chassis had successfully docked with the docking station, might it be possible to use the front PING sensor to determine when the robot chassis is correctly docked with the docking chassis? The front PING sensor could be set to detect the distance between the front of the robot chassis and the docking station and the docking station code could issue a Linear x: = 0.0 Twist command to stop the robot chassis?

Comments?

TCIII

TCIII commented 2 years ago

@chrisl8,

Bump?

I would really appreciate a response so I can move this project to completion.

Here is a link to the ArloBot performing basic autodocking without a dock.

TCIII

TCIII commented 2 years ago

@chrisl8,

I experimented again today with the autodocking system and found that the autodocking software is quite capable of driving headlong into the IR Transmitter and being perfectly centered on the beam.

Observation:

The robot starts with a CCW search to detect the IR beam and as a result the Left detector is the first detector to see the beam. Since both the Right and the Left sides of the detector mount are open, the Left detector will be illuminated before the robot has almost centered itself towards the beam. Therefore I think that is might be a good idea to shield both sides of the IR Receiver so that the FOV of each detector can be made narrower than it presently is in order to better center the robot on the IR beam.

Comments?

TCIII

TCIII commented 2 years ago

@chrisl8,

Bump?

TCIII

TCIII commented 2 years ago

@chrisl8,

I have found these high current pogo pins that can be used on the robot side to make contact with brass strips on the docking station.

I have built a fixture that attaches under the front PING mount and will support a plate to which the pogo pins can be mounted. I am also in the process of building the docking station that will house the IR Transmitter and the brass strip charging plates.

TCIII

TCIII commented 2 years ago

@chrisl8

Here are two photos of the IR Receiver and the Docking Probe from head-on and from above.

You can see the high current pogo pins in the center of the docking probe. There will be three pins each for the positive and negative power connections with the docking station to be able to handle both the battery charging and SBC/Accessories current requirements.

During recent testing the ir_Code.cpp code was able to bring the pogo pins to within 1/2 inch or less of the simulated docking station four inch wide brass contact strips. The docking station brass contact strips will be mounted on a moveable carriage backed by a set of springs. The ability of the brass contact strips carriage to move backward when being contacted by the ArloBot docking probe will insure positive contact between the docking station brass contacts and the ArloBot probe pogo contact.

The Escape distance of the forward PING sensor will have to be modified during the docking station maneuver in order for the docking probe to contact the docking station brass charging strips.

TCIII

IR_Receiver_Docking_Probe 001 IR_Receiver_Docking_Probe 002

TCIII commented 2 years ago

@chrisl8

Here is a prototype docking station that I have completed.

The pogo pins on the ArloBot docking probe contact the middle of the brass strips on the docking plate.

The docking plate is spring loaded and can move horizontally to allow for horizontal play between the ArloBot docking probe and the docking station.

The pogo pins on the docking probe can move 1/4 inch horizontally which will allow for slight off angle contact between the ArloBot docking probe and the contact plate on the docking station.

The black looking tube above the docking plate is the IR Transmitter IR LED that is encased in shrink sleeving to help narrow the IR beam.

TCIII Protype Docking Station 001

TCIII commented 2 years ago

@chrisl8,

Where have you gotten off to?

Regards, TCIII

chrisl8 commented 2 years ago

@TCIII

That is amazing! Lots of engineering there.

Life has gotten very busy for me. I'm still tinkering a bit, but not making enough progress on anything to report at the moment.

TCIII commented 2 years ago

@chrisl8,

Hi Chris,

Thanks for the response, much appreciated. I was getting a little worried there.

I believe that you have indicated that you would like to charge the battery and keep the SBC on line.

I picture two scenarios:

1) To do so will require a docking station power supply of around 5-6 amps at 16 vdc: ~1-2 amps for charging the battery and around 3-4 amps for the SBC and accessories. Having the SBC/Accessories on line while charging the battery will require a high current Schottky diode between the battery and the SBC/Accessories. The battery will charge at 14.4 vdc and the SBC/Accessories will run at 16 vdc. The Schottky diode will prevent current back flow from the 16 vdc being supplied to the SBC/Accessories. A the end of the battery charging cycle, the battery will be at a float voltage of ~13.6 vdc while the SBC/Accessories continue running at 16vdc. From my POV 5-6 amps is a lot of current and I have made allowances for that amount of current by having three pogo pins mounted horizontally in two rows for the positive and negative power connections on the docking probe. I have shown just one pogo pin in the center of the each row of the docking probe above so picture two more, one on each side of the center pogo pin. Likewise, the 1/2 inch wide brass strips are 1/16 inch thick to carry the current with minimal voltage drop.

2) Shutdown (remove power from) the SBC/Accessories once the ArloBot is docked and charge only the battery. This will require a relay between the battery and the SBC/Accessories that can remove power from the SBC/Accessories once the SBC has been commanded to shutdown. Once the battery reaches the 13.6 vdc float voltage, a timer circuit can determine when to energize the relay, startup the SBC/Accessories, and undock.

Comments?

TCIII This avoids the need for a 5-6 amp power supply.

chrisl8 commented 2 years ago

Why so many volts? My 12 volt chargers only go to like 14 volts I think, usually more like upper 13's. I think 14 is the max charging voltage for a 12 volt SLA battery isn't it, or something around 14, not 16?

Why so many amps? I'm only using a 1.1 amp charger and it is able to keep the Pi running while also toping off two SLA batteries. Without the Propeller boards, just using a Roboclaw, a Pi and a couple of other gadgets, my 750 milliamp chargers even do the job.

I feel like your setup is very different from mine if you need 16 volts at over 3 amps.