ROS (Robot Operating System) is an open-source robotics platform. Using it, robots can see, map, navigate, and interact with their environment using the latest algorithms. If you want to build complex robots, the pre-prepared ROS code can be used. ROS can be used with minimal resources. This can be installed on a Raspberry Pi-level computer.
As an introduction to ROS, let's look at how to control servos. The drawback of servos is that they respond to commands very quickly, often causing sudden head movements and loss of balance. However, with ROS, sinusoidal motion can be performed, keeping the robot stable. Since this can be done within ROS, there's no need to rewrite the control program code. Furthermore, the program code connecting the servo and ROS, as well as the servo hardware, do not need to be changed. Moreover, the program code can be used freely.
ROS works well on Ubuntu or Debian without needing to be compiled. To set it up, you need to run Ubuntu on a Linux machine, using a hobby server, Arduino, and standard wiring. ROS boots from the Ubuntu machine, and messages are transmitted to the Arduino via USB. Installing the binary ROS package will add the following instructions to the console program (such as gnome-terminal or konsole) so that the Arduino system can recognize the ROS library.
cd ~/sketchbook/libraries
rm-rfros_lib
rosrunrosserial_arduinomake_libraries.py.
Arduino program
Next, the program code needs to be uploaded to the Arduino to execute low-level servo control so that it can be operated from the Linux machine. At this point, the servo position needs to be specified as a percentage (0.0~1.0) within a limited range. The reason for using a percentage instead of specifying an angle is that the Arduino program code restricts the correct angle, and conflicts should be avoided when specifying the angle.
As you can see, using ROS makes regular loop functions quite simple. Loop functions only subscribe to data; this applies to all Arduino loops. During setup, ROS needs to be initialized, and the subscriptions for each ROS message subscriber must be enabled. Each subscriber will occupy Arduino RAM; the number depends on what the program code will do, but is limited to 6 to 12.
#include
#include
#include
#include
#defineSERVOPIN3
Servoservo;
voidservo_cb(conststd_msgs::Float32&msg)
{
constfloatmin=45;
constfloatrange = 90;
floatv = msg.data;
if (v>1)v=1;
if (v < 0) v = 0;
floatangle = min + (range * v);
servo.write(angle);
}
ros::Subscriber
ros::NodeHandlenh;
voidsetup()
{
servo.attach(SERVOPIN);
nh.initNode();
nh.subscribe(sub);
}
voidloop()
{
nh.spinOnce();
delay(1);}
Next, we need to figure out how to communicate with Arduino in the ROS world. The simplest way is to use a robot startup file. Although the following file content is very simple, we need to add a startup file here so that even very complex robots can be started with a single command.
$catrosservo.launch
$roslaunch./rosservo.lanch
The `rostopic` command indicates which part of the robot the ROS message is sent to. Looking at the code below, you'll see that `/head/tilt` can be used via Arduino. Messages must be transmitted using `rostopic`. The -1 option only publishes the message once, instructing `/head/tilt` to send a floating-point number.
$rostopiclist
/diagnostics
/head/tilt
/rosout
/rosout_agg
$rostopicpub-1/head/tiltstd_msgs/Float320.4
$rostopicpub-1/head/tiltstd_msgs/Float320.9
During this phase, all known methods for publishing values to ROS can be used to control the server. If the value is changed from 0 to 1, the server will run at full speed. This is fine in itself, but in reality, we want to gradually accelerate to full speed and then gradually decelerate to stop at the target angle. If the server suddenly starts running, the robot's movements will become stiff, startling those around it.
Smooth motion using another node
Houndbot
Terry
Terry and Houndbot are both ROS robots, constructed from 6061 aluminum alloy parts. The project's goal is to enable these robots to move autonomously as much as possible.
The following Python script listens for messages at "/head/tilt/smooth" and sends numerous messages to "/head/tilt" to gradually accelerate and delay the rotation before the server reaches the target angle. Each time a message arrives at "/head/tilt/smooth", it calls "moveServo_cb". This callback function generates a value every 10 degrees between -90 and +90 degrees, appending it to the angle array. "sin()" takes this angle, incrementing the value from -1 to +1. After incrementing the value by 1, the range becomes 0 to +2. Dividing by 2 completes the array of curve values from 0 to +1. Looking at the m array, each time a message is sent, it advances slightly, within the range of r, until it reaches 1*r or the full range.
#!/usr/bin/envpython
fromtimeimportsleep
import numpyasnp
importrospy
fromstd_msgs.msgimportFloat32
currentPosition=0.5
pub=None
defmoveServo_cb(data):
globalcurrentPosition,pub
targetPosition=data.data
r=targetPosition-currentPosition
angles=np.array((range(190))[0::10])-90
m=(np.sin(angles*np.pi/180.)+1)/2
formiinnp.nditer(m):
pos = currentPosition + mi * r
print "pos:", pos
pub.publish(pos)
sleep(0.05)
currentPosition=targetPosition
print "pos-e:",currentPosition
pub.publish(currentPosition)
deflistener():
globalpub
rospy.init_node('servoencoder',anonymous=True)
rospy.Subscriber('/head/tilt/smooth',Float32,moveServo_cb)
pub=rospy.Publisher('/head/tilt',Float32,queue_size=10)
rospy.spin()
if __name__=='__main__':
listener()
To test the smooth operation of the server, you need to start a Python script and post messages to "/head/tilt/smooth" to view the smooth operation.
$./servoencoder.py
$rostopicpub-1/head/tilt/smoothstd_msgs/Float321
$rostopicpub-1/head/tilt/smoothstd_msgs/Float320
In ROS, names can also be remapped. By simply remapping "/head/tilt/smooth" to "/head/tilt", the program can send commands to the server without being aware that the sine curve values are changing.
Embracing the Future
While this only illustrates basic servo control, ROS offers much more. If you want to know what's hindering the robot, you can use Kinect, which already supports ROS. Even if the navigation stack uses this data mapping, you can feed in short Python scripts to get the servos moving and command the robot to track nearby objects. Yes, eyes really do follow objects.
Terry is an indoor robot equipped with two Kinects. One is used for navigation, and the other for depth mapping. Terry uses six Arduinos and can be operated directly from a ROS-enabled network interface or a PS3 remote.
Houndbot is designed for outdoor use. It includes a remote control, GPS, compass, and ROS ear-shaped controller. Future plans include adding a PS4 dual-lens camera for navigation, as Kinect cannot be used in sunlight. The robot weighs 20 kg. A suspension system can also be added, requiring custom-made aluminum alloy parts.
Disclaimer: This article is a reprint. If it involves copyright issues, please contact us promptly for deletion (QQ: 2737591964 ) . We apologize for any inconvenience.