biped_teleop.cpp
Go to the documentation of this file.
00001 #include "ros/ros.h"
00002 #include "visualization_msgs/MarkerArray.h"
00003 #include "visualization_msgs/Marker.h"
00004 #include "geometry_msgs/PoseStamped.h"
00005 #include "tf/transform_broadcaster.h"
00006 #include "tf/transform_listener.h"
00007 #include "biped_robin_msgs/StepTarget3DService.h"
00008 #include "std_srvs/Empty.h"
00009 #include "std_msgs/UInt8.h"
00010 #include <math.h>
00011 
00012 /*
00013 Dieser Knoten empfängt eine Geschwindigkeitsvorgabe von bipedRobin_teleop/biped_joy_node, und erzeugt daraus Schritte.
00014 Schritt werden nur gesendet wenn der Schrittbuffer im Roboter leer ist.
00015 Die Anzahl der Schritt im Buffer wird vom bipedRobin_driver/biped_deserializer empfangen
00016 Die auszuführen Schritte werden an bipedRobin_driver/biped_serializer gesendet
00017 */
00018 
00019 #define DEF_LEG_DISTANCE 0.25
00020 #define MIN_LEG_DISTANCE 0.22
00021 #define MAX_LEG_DISTANCE 0.3
00022 
00023 #define MAX_STEP_LENGTH 0.1
00024 #define MAX_STEP_ANGLE 3.1415/8
00025 
00026 ros::ServiceClient footstepInc_client; //sends Steps to the serializer
00027 ros::Publisher goalVizPub;
00028 
00029 geometry_msgs::PoseStamped goalViz;
00030 
00031 int currentLegToMove = 1; //0.. right leg, 1.. left leg
00032 bool sendStep = true; //Flag if we shoud send a step at time sendStepTime
00033 int wasWalking = false; //flag that says if the robot was previously walking to know when to make the last step
00034 
00035 ros::Time lastCallbackTime;
00036 ros::Time thisCallbackTime;
00037 ros::Time sendStepTime;
00038 
00039 //TODO: use TF to get current position of the robot
00040 tf::Transform desiredCenterPoint (tf::createQuaternionFromYaw(0), tf::Point(0, 0.271/2, 0));
00041 tf::Transform desiredLeftLeg (tf::createQuaternionFromYaw(0), tf::Point(0, 0.271, 0));
00042 tf::Transform desiredRightLeg (tf::createQuaternionFromYaw(0), tf::Point(0, 0, 0));
00043 
00044 template <typename T> int sgn(T val) {
00045     return (T(0) < val) - (val < T(0));
00046 }
00047 
00048 void visualize() {
00049         goalViz.header.seq++;
00050         goalViz.header.stamp = thisCallbackTime;
00051         goalViz.header.frame_id = "odom";
00052 
00053         goalViz.pose.position.x = desiredCenterPoint.getOrigin().x(); //desiredCenterPoint
00054         goalViz.pose.position.y = desiredCenterPoint.getOrigin().y();
00055         goalViz.pose.position.z = desiredCenterPoint.getOrigin().z();
00056 
00057         goalViz.pose.orientation.x = desiredCenterPoint.getRotation().getX();
00058         goalViz.pose.orientation.y = desiredCenterPoint.getRotation().getY();
00059         goalViz.pose.orientation.z = desiredCenterPoint.getRotation().getZ();
00060         goalViz.pose.orientation.w = desiredCenterPoint.getRotation().getW();
00061 
00062         goalVizPub.publish(goalViz);
00063 }
00064 
00065 
00066 void twistCallback(const geometry_msgs::Twist twist) {
00067         biped_robin_msgs::StepTarget3DService srv;
00068 
00069         thisCallbackTime = ros::Time::now();
00070 
00071         // update desired center point
00072         double deltaTime = 0.01;
00073         tf::Pose deltaCenterPoint (tf::createQuaternionFromYaw(twist.angular.z * deltaTime), tf::Point(twist.linear.x * deltaTime, twist.linear.y * deltaTime, 0.0));
00074         desiredCenterPoint = desiredCenterPoint * deltaCenterPoint;
00075 
00076         /*// TODO: saturate desired Center Point
00077         tf::Transform deltaStanceCenter;
00078         if (currentLegToMove == 0) { //right leg
00079                 deltaStanceCenter = desiredCenterPoint.inverse() * desiredLeftLeg;
00080         } else { //left leg
00081                 deltaStanceCenter = desiredCenterPoint.inverse() * desiredRightLeg;
00082         }
00083         double deltaX = deltaStanceCenter.getOrigin().getX();
00084         double deltaY = deltaStanceCenter.getOrigin().getY();
00085         double deltaG = tf::getYaw(deltaStanceCenter.getRotation());
00086         ROS_INFO("%f %f %f",deltaX,deltaY,deltaG);*/
00087 
00088 
00089 
00090         if (sendStep && (thisCallbackTime - sendStepTime).toSec() > 0 && (twist.linear.x != 0 || twist.linear.y != 0 || twist.angular.z != 0 || wasWalking > 0)) { //sendStep flag is set and velocity is nonzero or is first time zero  --> calculate next step and send it
00091 
00092                 //figure out the next swing leg position and the relativ step
00093                 tf::Transform deltaCenterSwing;
00094                 tf::Transform step;
00095                 if (currentLegToMove == 0) { //right leg
00096                         deltaCenterSwing.setOrigin(tf::Point(0.0, -DEF_LEG_DISTANCE/2, 0.0));
00097                         deltaCenterSwing.setRotation(tf::createQuaternionFromYaw(0.0));
00098                         desiredRightLeg = desiredCenterPoint * deltaCenterSwing;   //place swing leg next to the desired center point
00099                         step = desiredLeftLeg.inverse() * desiredRightLeg;
00100                 } else { //left leg
00101                         deltaCenterSwing.setOrigin(tf::Point(0.0, DEF_LEG_DISTANCE/2, 0.0));
00102                         deltaCenterSwing.setRotation(tf::createQuaternionFromYaw(0.0));
00103                         desiredLeftLeg = desiredCenterPoint * deltaCenterSwing;   //place swing leg next to the desired center point
00104                         step = desiredRightLeg.inverse() * desiredLeftLeg;
00105                 }
00106 
00107                 //check if the step is feasible
00108                 double deltaX = step.getOrigin().x();
00109                 double deltaY = step.getOrigin().y();
00110                 double deltaG = tf::getYaw(step.getRotation());
00111 
00112                 deltaX = sgn(deltaX) * fmin(fabs(deltaX), MAX_STEP_LENGTH);
00113                 deltaY = sgn(deltaY) * fmax(fmin(fabs(deltaY), MAX_LEG_DISTANCE), MIN_LEG_DISTANCE);
00114                 deltaG = sgn(deltaG) * fmin(fabs(deltaG), MAX_STEP_ANGLE);
00115 
00116                 tf::Pose satStep (tf::createQuaternionFromYaw(deltaG), tf::Point(deltaX, deltaY, 0.0));
00117                 if (currentLegToMove == 0) { //right leg
00118                         desiredRightLeg = desiredLeftLeg * satStep;
00119                         desiredCenterPoint = desiredRightLeg * deltaCenterSwing.inverse();
00120                 } else { //left leg
00121                         desiredLeftLeg = desiredRightLeg * satStep;
00122                         desiredCenterPoint = desiredLeftLeg * deltaCenterSwing.inverse();
00123                 }
00124 
00125                 // set the data for the step service and call it
00126                 srv.request.step.pose.position.x = satStep.getOrigin().getX();
00127                 srv.request.step.pose.position.y = satStep.getOrigin().getY();
00128                 srv.request.step.pose.position.z = satStep.getOrigin().getZ();
00129                 srv.request.step.pose.orientation.x = satStep.getRotation().getX();
00130                 srv.request.step.pose.orientation.y = satStep.getRotation().getY();
00131                 srv.request.step.pose.orientation.z = satStep.getRotation().getZ();
00132                 srv.request.step.pose.orientation.w = satStep.getRotation().getW();
00133                 srv.request.step.leg = currentLegToMove;
00134                 footstepInc_client.call(srv); //call service
00135 
00136                 // update next leg to move
00137                 if (currentLegToMove == 0) {
00138                         currentLegToMove = 1;
00139                 } else {
00140                         currentLegToMove = 0;
00141                 }
00142 
00143                 // check if this was the last step and the robot should move his legs parallel
00144                 if (wasWalking <= 0) wasWalking = 2; //we need to final steps
00145                 if (twist.linear.x == 0 && twist.linear.y == 0 && twist.angular.z == 0) wasWalking--;
00146 
00147                 sendStep = false; //wait till next step is asked by robot
00148         }
00149 
00150         visualize();
00151 
00152         lastCallbackTime = ros::Time::now();
00153 }
00154 
00155 void stepsLeftCallback(std_msgs::UInt8 stepsLeftInBuffer) {
00156         if(stepsLeftInBuffer.data == 0){ //keine Schritte mehr im Buffer
00157                 //ros::Duration(0.8).sleep(); //warten bevor neuer Schritt gesendet wird
00158                 sendStep = true;
00159                 sendStepTime = ros::Time::now() + ros::Duration(0.8);
00160         }
00161 }
00162 
00163 
00164 
00165 int main(int argc, char **argv)
00166 {
00167   /* init ROS */
00168 
00169         ros::init(argc, argv, "biped_teleop");
00170 
00171         ros::NodeHandle n;
00172         ros::NodeHandle pn("~");
00173 
00174         //client zum senden der Schritt an den serializer
00175         footstepInc_client = n.serviceClient<biped_robin_msgs::StepTarget3DService>("footstep3DInc_srv");
00176         //subscriber zum Einlesen der Anzahl der Schritte im Buffer
00177         ros::Subscriber stepsLeftInBuffer_sub = n.subscribe<std_msgs::UInt8>("stepsLeftInBuffer", 1, stepsLeftCallback);
00178         //subscriber zum Einlesen der geschwindigkeit vom biped_joy_node
00179         ros::Subscriber twist = n.subscribe<geometry_msgs::Twist>("/cmd_vel", 1, twistCallback);
00180 
00181         goalVizPub = pn.advertise<geometry_msgs::PoseStamped>("desiredCenterPoint", 10);
00182 
00183         //reste visualization
00184         ros::Duration(0.5).sleep();
00185         visualize();
00186 
00187         ros::spin();
00188 
00189         return 0;
00190 }
00191 
00192 


biped_robin_teleop
Author(s): Johannes Mayr, Johannes Mayr
autogenerated on Mon Jan 6 2014 11:09:14