/** * @brief AdmittanceParamManager::init * Initializes this class by starting the reconfig server. * @param nh NodeHandle in which the reconfig server is running */ void AdmittanceParamManager::init(ros::NodeHandle& nh) { // Set up dynamic reconfigure for admittance params ros::NodeHandle nh_params(nh, "admittance_params/"); param_reconfig_server_.reset(new AdmittanceDynamicReconfigServer(param_reconfig_mutex_, nh_params)); param_reconfig_callback_ = boost::bind(&AdmittanceParamManager::dynamicReconfigCB, this, _1, _2); param_reconfig_server_->setCallback(param_reconfig_callback_); }
int main(int argc, char** argv) { ros::init(argc, argv, "controller"); ros::NodeHandle nh; ros::NodeHandle nh_params("~"); ROS_INFO("running controller"); ros::Subscriber imu_sub = nh.subscribe("/firefly/imu", 1, &imuCallback); ros::Subscriber pose_sub = nh.subscribe("/firefly/fake_gps/pose", 1, &poseCallback); ros::Subscriber traj_sub = nh.subscribe("command/trajectory", 1, &MultiDofJointTrajectoryCallback); current_index = 0; double x_kp, x_ki, x_kd, y_kp, y_ki, y_kd, z_kp, z_ki, z_kd, yaw_kp, yaw_ki, yaw_kd, roll_limit, pitch_limit, yaw_limit, thrust_limit; nh_params.param("x_kp", x_kp, 1.0); nh_params.param("x_ki", x_ki, 0.0); nh_params.param("x_kd", x_kd, 0.0); nh_params.param("y_kp", y_kp, 1.0); nh_params.param("y_ki", y_ki, 0.0); nh_params.param("y_kd", y_kd, 0.0); nh_params.param("z_kp", z_kp, 1.0); nh_params.param("z_ki", z_ki, 0.0); nh_params.param("z_kd", z_kd, 0.0); nh_params.param("yaw_kp", yaw_kp, 1.0); nh_params.param("yaw_ki", yaw_ki, 0.0); nh_params.param("yaw_kd", yaw_kd, 0.0); nh_params.param("roll_limit", roll_limit, 0.0); nh_params.param("pitch_limit", pitch_limit, 0.0); nh_params.param("thrust_limit", thrust_limit, 0.0); nh_params.param("yaw_limit", yaw_limit, 0.0); // Chose one of the versions below. The first of these topic published determines the control mode. ros::Publisher command_pub = nh.advertise<mav_msgs::RollPitchYawrateThrust>("command/roll_pitch_yawrate_thrust", 1); // Start the dynamic_reconfigure server dynamic_reconfigure::Server<rotors_exercise::ControllerConfig> server; dynamic_reconfigure::Server<rotors_exercise::ControllerConfig>::CallbackType f; f = boost::bind(&reconfigure_callback, _1, _2); server.setCallback(f); ROS_INFO("Initializing controller ... "); /* Initialize here your controllers */ ros::Timer timer; timer = nh.createTimer(ros::Duration(0.2), timerCallback); //Timer for debugging // Run the control loop and Fly to x=0m y=0m z=1m ROS_INFO("Going to starting position [0,0,1] ..."); //positionLoop.setPoint(0.0, 0.0, 1.0, 0.0); setpoint_pos = tf::Vector3(0.,0.,1.); setpoint_yaw = 0.0; latest_pose_update_time = ros::Time::now(); while(ros::ok()) { ros::spinOnce(); delta_time_pose = (latest_pose.header.stamp - latest_pose_update_time).toSec() ; // Check if pose/imu/state data was received if ( (latest_pose.header.stamp.nsec > 0.0) && ((latest_pose.header.stamp - latest_pose_update_time).toSec() > 0.0) ) { latest_pose_update_time = latest_pose.header.stamp; //compute distance to next waypoint double distance = sqrt((setpoint_pos[0]-latest_pose.pose.position.x) * (setpoint_pos[0]-latest_pose.pose.position.x) + (setpoint_pos[1]-latest_pose.pose.position.y) * (setpoint_pos[1]-latest_pose.pose.position.y) + (setpoint_pos[2]-latest_pose.pose.position.z) * (setpoint_pos[2]-latest_pose.pose.position.z) ); if (distance < 0.5) { //there is still waypoints if (current_index < latest_trajectory.poses.size()) { ROS_INFO("Waypoint achieved! Moving to next waypoint"); geometry_msgs::PoseStamped wp; wp = latest_trajectory.poses[current_index]; setpoint_pos[0]=wp.pose.position.x; setpoint_pos[1]=wp.pose.position.y; setpoint_pos[2]=wp.pose.position.z; setpoint_yaw=tf::getYaw(wp.pose.orientation); current_index++; }else if (current_index == latest_trajectory.poses.size()) // print once waypoint achieved { ROS_INFO("Waypoint achieved! No more waypoints. Hovering"); current_index++; } } // run position loop double now = (double)ros::Time::now().toSec(); double delta_time = now - latest; latest = now; ROS_INFO_STREAM("1"); //Calculate error for each component latest_yaw = tf::getYaw(latest_pose.pose.orientation); ROS_INFO_STREAM("latest yaw: " << latest_yaw); ROS_INFO_STREAM("setpoint_pos: " << setpoint_pos); ROS_INFO_STREAM("latest_pose: " << latest_pose); computeError(setpoint_pos,latest_pose,setpoint_yaw, latest_yaw, error); //PROPORCIONAL Kp*error // DONE ON GET COMMANDS //INTEGRAL integral(error, delta_time, integral_limits, integral_error_accumulator); //DERIVATIVE derivative(error,delta_time, delta_error, previous_error); //Get commands x_vel_cmd = x_kp*error[0] + x_ki*integral_error_accumulator[0] + x_kd*delta_error[0]; y_vel_cmd = y_kp*error[1] + y_ki*integral_error_accumulator[1] + y_kd*delta_error[1]; z_vel_cmd = z_kp*error[2] + z_ki*integral_error_accumulator[2] + z_kd*delta_error[2]; yaw_rate = yaw_kp*error[3] + yaw_ki*integral_error_accumulator[3] + yaw_kd*delta_error[3]; // your desired velocities (or accelerations) should be stored in // x_vel_cmd, // y_vel_cmd, // z_vel_cmd, // yaw_rate wrap around!!!! //x_accel_cmd = x_vel_cmd // Map velocities (or accelerations) to angles roll, pitch roll_cmd = (x_vel_cmd*sin(latest_yaw) + y_vel_cmd*cos(latest_yaw))/GRAVETAT; pitch_cmd = (x_vel_cmd*cos(latest_yaw) + y_vel_cmd*sin(latest_yaw))/GRAVETAT; thrust = 1.5*GRAVETAT + 1.5*z_vel_cmd; //Rotate TF from WORLD TO BODY FRAME ------ARDRONE //tf::Vector3 vector3 (x_vel_cmd , y_vel_cmd, 0.0); //vector3 = rotateZ (vector3, -tf::getYaw(latest_pose.pose.orientation)); //pitch_cmd = vector3[0]; //roll_cmd = vector3[1]; //thrust = z_vel_cmd; // Saturate your request roll_cmd = (roll_cmd > roll_limit) ? roll_limit : ((roll_cmd < -roll_limit) ? -roll_limit : roll_cmd); pitch_cmd = (pitch_cmd > pitch_limit) ? pitch_limit : ((pitch_cmd < -pitch_limit)? -pitch_limit : pitch_cmd); thrust = (thrust > thrust_limit) ? thrust_limit: ((thrust < -thrust_limit) ? -thrust_limit: thrust); yaw_rate = (yaw_rate > yaw_limit) ? yaw_limit : ((yaw_rate < -yaw_limit) ? -yaw_limit : yaw_rate); // Send to the attitude controller: // roll angle [rad], pitch angle [rad], thrust [N][rad/s] mav_msgs::RollPitchYawrateThrust msg; msg.header = latest_pose.header; // use the latest information you have. msg.roll = -roll_cmd; msg.pitch = pitch_cmd; msg.thrust.z = thrust; msg.yaw_rate = yaw_rate; command_pub.publish(msg); } ros::Duration(control_loop_period/2.).sleep(); // may be set slower. } return 0; }