Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00022 #include <ros/ros.h>
00023
00024 #include <angles/angles.h>
00025 #include <driver_base/SensorLevels.h>
00026 #include <dynamic_reconfigure/server.h>
00027
00028 #include "device_impl.h"
00029
00030 #include <art_msgs/ArtVehicle.h>
00031 #include <art_msgs/ArtHertz.h>
00032 #include <art_msgs/CarDriveStamped.h>
00033 #include <art_msgs/CarCommand.h>
00034 #include <art_msgs/Epsilon.h>
00035 #include <art_msgs/Gear.h>
00036 #include <art_msgs/LearningCommand.h>
00037 #include <art_msgs/PilotState.h>
00038
00039 #include <art/conversions.h>
00040 #include <art/steering.h>
00041
00042 #include <art_pilot/PilotConfig.h>
00043 typedef art_pilot::PilotConfig Config;
00044
00045 #include "accel.h"
00046
00047 typedef art_msgs::DriverState DriverState;
00048 using art_msgs::Epsilon;
00049
00050
00082 class PilotNode
00083 {
00084 public:
00085
00086 PilotNode(ros::NodeHandle node);
00087 void spin(void);
00088
00089 private:
00090
00091 void adjustSteering(void);
00092 void halt(void);
00093 void monitorHardware(void);
00094 void processCarDrive(const art_msgs::CarDriveStamped::ConstPtr &msg);
00095 void processCarCommand(const art_msgs::CarCommand::ConstPtr &msg);
00096 void processLearning(const art_msgs::LearningCommand::ConstPtr &learningIn);
00097 void reconfig(Config &newconfig, uint32_t level);
00098 void speedControl(void);
00099 void validateTarget(void);
00100
00101 bool is_shifting_;
00102
00103 typedef dynamic_reconfigure::Server<Config> ReconfigServer;
00104 boost::shared_ptr<ReconfigServer> reconfig_server_;
00105
00106
00107 ros::Subscriber accel_cmd_;
00108 ros::Subscriber car_cmd_;
00109
00110
00111 boost::shared_ptr<device_interface::DeviceBrake> brake_;
00112 boost::shared_ptr<device_interface::DeviceImu> imu_;
00113 boost::shared_ptr<device_interface::DeviceOdom> odom_;
00114 boost::shared_ptr<device_interface::DeviceShifter> shifter_;
00115 boost::shared_ptr<device_interface::DeviceSteering> steering_;
00116 boost::shared_ptr<device_interface::DeviceThrottle> throttle_;
00117
00118 ros::Subscriber learning_cmd_;
00119
00120 ros::Publisher pilot_state_;
00121
00122
00123 Config config_;
00124 ros::Duration timeout_;
00125
00126 ros::Time current_time_;
00127
00128
00129 ros::Time goal_time_;
00130
00131 art_msgs::PilotState pstate_msg_;
00132
00133 boost::shared_ptr<pilot::AccelBase> accel_;
00134 };
00135
00136
00138
00140
00142 PilotNode::PilotNode(ros::NodeHandle node):
00143 is_shifting_(false),
00144 reconfig_server_(new dynamic_reconfigure::Server<Config>)
00145 {
00146
00147
00148 reconfig_server_->setCallback(boost::bind(&PilotNode::reconfig,
00149 this, _1, _2));
00150
00151
00152 brake_.reset(new device_interface::DeviceBrake(node));
00153 imu_.reset(new device_interface::DeviceImu(node));
00154 odom_.reset(new device_interface::DeviceOdom(node));
00155 shifter_.reset(new device_interface::DeviceShifter(node));
00156 steering_.reset(new device_interface::DeviceSteering(node));
00157 throttle_.reset(new device_interface::DeviceThrottle(node));
00158
00159
00160 ros::TransportHints noDelay = ros::TransportHints().tcpNoDelay(true);
00161 int qDepth = 1;
00162
00163
00164 accel_cmd_ = node.subscribe("pilot/drive", qDepth,
00165 &PilotNode::processCarDrive, this, noDelay);
00166 car_cmd_ = node.subscribe("pilot/cmd", qDepth,
00167 &PilotNode::processCarCommand, this , noDelay);
00168 learning_cmd_ = node.subscribe("pilot/learningCmd", qDepth,
00169 &PilotNode::processLearning, this, noDelay);
00170
00171
00172 pilot_state_ = node.advertise<art_msgs::PilotState>("pilot/state", qDepth);
00173 pstate_msg_.header.frame_id = art_msgs::ArtVehicle::frame_id;
00174 }
00175
00177 void PilotNode::spin(void)
00178 {
00179
00180 ros::Rate cycle(art_msgs::ArtHertz::PILOT);
00181 while(ros::ok())
00182 {
00183 ros::spinOnce();
00184
00185 monitorHardware();
00186
00187
00188 speedControl();
00189 adjustSteering();
00190
00191 pilot_state_.publish(pstate_msg_);
00192
00193 cycle.sleep();
00194 }
00195 }
00196
00197
00199
00201
00213 void PilotNode::adjustSteering(void)
00214 {
00215 if (config_.human_steering)
00216 return;
00217
00218 if (fabs(pstate_msg_.target.steering_angle
00219 - pstate_msg_.current.steering_angle)
00220 > Epsilon::steering_angle)
00221 {
00222
00223 float steer_degrees =
00224 angles::to_degrees(pstate_msg_.target.steering_angle);
00225 ROS_DEBUG("requesting steering angle = %.1f (degrees)", steer_degrees);
00226 steering_->publish(steer_degrees, current_time_);
00227 }
00228 }
00229
00245 void PilotNode::halt(void)
00246 {
00247
00248 float abs_speed = pstate_msg_.current.speed;
00249 if (abs_speed < Epsilon::speed)
00250 {
00251
00252
00253
00254 brake_->publish(config_.brake_hold, current_time_);
00255 }
00256 else
00257 {
00258
00259
00260
00261
00262
00263
00264 throttle_->publish(0.0, current_time_);
00265 brake_->publish(1.0, current_time_);
00266 }
00267 accel_->reset();
00268 }
00269
00275 void PilotNode::monitorHardware(void)
00276 {
00277
00278 current_time_ = ros::Time::now();
00279 pstate_msg_.header.stamp = current_time_;
00280 pstate_msg_.current.acceleration = fabs(imu_->value());
00281 pstate_msg_.current.speed = fabs(odom_->value());
00282 pstate_msg_.current.steering_angle =
00283 angles::from_degrees(steering_->value());
00284 pstate_msg_.current.gear.value = shifter_->value();
00285
00286
00287
00288 ros::Time recently;
00289 if (current_time_ > (recently + timeout_))
00290 {
00291 recently = current_time_ - timeout_;
00292 }
00293
00294
00295 pstate_msg_.brake.state = brake_->state(recently);
00296 pstate_msg_.imu.state = imu_->state(recently);
00297 pstate_msg_.odom.state = odom_->state(recently);
00298 pstate_msg_.shifter.state = shifter_->state(recently);
00299 pstate_msg_.steering.state = steering_->state(recently);
00300 pstate_msg_.throttle.state = throttle_->state(recently);
00301
00303
00304 pstate_msg_.pilot.state = DriverState::RUNNING;
00305 if (pstate_msg_.brake.state != DriverState::RUNNING
00306 || pstate_msg_.imu.state != DriverState::RUNNING
00307 || pstate_msg_.odom.state != DriverState::RUNNING
00308 || (!config_.human_steering
00309 && pstate_msg_.steering.state != DriverState::RUNNING)
00310 || pstate_msg_.throttle.state != DriverState::RUNNING)
00311 {
00312
00313 pstate_msg_.pilot.state = DriverState::OPENED;
00314 ROS_WARN_THROTTLE(40, "critical component failure, pilot not running");
00315
00316 pstate_msg_.target = art_msgs::CarDrive();
00317 }
00318 }
00319
00321 void PilotNode::processCarDrive(const art_msgs::CarDriveStamped::ConstPtr &msg)
00322 {
00323 goal_time_ = msg->header.stamp;
00324 pstate_msg_.target = msg->control;
00325 validateTarget();
00326 }
00327
00329 void PilotNode::processCarCommand(const art_msgs::CarCommand::ConstPtr &msg)
00330 {
00331 ROS_WARN_THROTTLE(100, "CarCommand deprecated: use CarDriveStamped.");
00332
00333 goal_time_ = msg->header.stamp;
00334 pstate_msg_.target.steering_angle = angles::from_degrees(msg->control.angle);
00335 pstate_msg_.target.behavior.value = art_msgs::PilotBehavior::Run;
00336
00337 pstate_msg_.target.jerk = 0.0;
00338 pstate_msg_.target.acceleration = 0.0;
00339 pstate_msg_.target.speed = msg->control.velocity;
00340 if (pstate_msg_.target.speed > 0.0)
00341 {
00342 pstate_msg_.target.gear.value = art_msgs::Gear::Drive;
00343 }
00344 else if (pstate_msg_.target.speed < 0.0)
00345 {
00346
00347 pstate_msg_.target.speed = -msg->control.velocity;
00348 pstate_msg_.target.gear.value = art_msgs::Gear::Reverse;
00349 }
00350 else
00351 {
00352 pstate_msg_.target.gear.value = art_msgs::Gear::Naught;
00353 }
00354
00355 validateTarget();
00356 }
00357
00359 void PilotNode::processLearning(const art_msgs::LearningCommand::ConstPtr
00360 &learningIn)
00361 {
00362 ROS_WARN_THROTTLE(100, "LearningCommand deprecated: use CarDriveStamped.");
00363 pstate_msg_.preempted = (learningIn->pilotActive == 0);
00364 ROS_INFO_STREAM("Pilot is "
00365 << (pstate_msg_.preempted? "preempted": "active"));
00366 }
00367
00377 void PilotNode::reconfig(Config &newconfig, uint32_t level)
00378 {
00379 ROS_INFO("pilot dynamic reconfigure, level 0x%08x", level);
00380
00381 if (level & driver_base::SensorLevels::RECONFIGURE_CLOSE)
00382 {
00383
00384 accel_ = pilot::allocAccel(newconfig);
00385 }
00386 else
00387 {
00388
00389 accel_->reconfigure(newconfig);
00390 }
00391
00392 config_ = newconfig;
00393 timeout_ = ros::Duration(config_.timeout);
00394 }
00395
00396
00405 void PilotNode::speedControl(void)
00406 {
00407
00408
00409 if (pstate_msg_.preempted)
00410 return;
00411
00412 float dt = 1.0 / art_msgs::ArtHertz::PILOT;
00413 float abs_current_speed = pstate_msg_.current.speed;
00414 float abs_target_speed = pstate_msg_.target.speed;
00415
00416 if (is_shifting_)
00417 {
00418 if (shifter_->is_reset())
00419 {
00420
00421 is_shifting_ = false;
00422 }
00423 else if (!shifter_->busy())
00424 {
00425
00426 shifter_->publish(art_msgs::Shifter::Reset, current_time_);
00427 }
00428 }
00429
00430 if (pstate_msg_.current.gear.value == pstate_msg_.target.gear.value
00431 || pstate_msg_.target.gear.value == art_msgs::Gear::Naught)
00432 {
00433
00434 if ((pstate_msg_.pilot.state != DriverState::RUNNING)
00435 || (pstate_msg_.target.gear.value == art_msgs::Gear::Park)
00436 || (pstate_msg_.target.gear.value == art_msgs::Gear::Neutral)
00437 || shifter_->busy())
00438 {
00439
00440 halt();
00441 }
00442 else
00443 {
00444
00445 if ((abs_target_speed < Epsilon::speed)
00446 && ((pstate_msg_.target.acceleration == 0.0)
00447 || (pstate_msg_.target.acceleration * dt
00448 > abs_current_speed)))
00449 {
00450
00451
00452 halt();
00453 }
00454 else
00455 {
00456
00457 accel_->adjust(pstate_msg_, brake_, throttle_);
00458 }
00459 }
00460 }
00461 else
00462 {
00463
00464 is_shifting_ = true;
00465 if (!shifter_->busy())
00466 {
00467
00468 shifter_->publish(pstate_msg_.target.gear.value, current_time_);
00469 }
00470
00471 halt();
00472 }
00473 }
00474
00475
00477 void PilotNode::validateTarget(void)
00478 {
00479
00480 if (pstate_msg_.target.speed < 0.0
00481 || pstate_msg_.target.acceleration < 0.0
00482 || pstate_msg_.target.jerk < 0.0)
00483 {
00484 ROS_WARN_THROTTLE(100, "Negative speed, acceleration and jerk "
00485 "are DEPRECATED (using absolute value).");
00486 pstate_msg_.target.speed = fabs(pstate_msg_.target.speed);
00487 pstate_msg_.target.acceleration = fabs(pstate_msg_.target.acceleration);
00488 pstate_msg_.target.jerk = fabs(pstate_msg_.target.jerk);
00489 }
00490
00491 if (pstate_msg_.target.gear.value == art_msgs::Gear::Reverse)
00492 {
00493 if (pstate_msg_.target.speed > config_.limit_reverse)
00494 {
00495 ROS_WARN_STREAM_THROTTLE(100, "Requested speed ("
00496 << pstate_msg_.target.speed
00497 << ") exceeds reverse limit of "
00498 << config_.limit_reverse
00499 << " m/s");
00500 pstate_msg_.target.speed = config_.limit_reverse;
00501 }
00502 }
00503 else
00504 {
00505 if (pstate_msg_.target.speed > config_.limit_forward)
00506 {
00507 ROS_WARN_STREAM_THROTTLE(100, "Requested speed ("
00508 << pstate_msg_.target.speed
00509 << ") exceeds limit of "
00510 << config_.limit_forward
00511 << " m/s");
00512 pstate_msg_.target.speed = config_.limit_forward;
00513 }
00514 }
00515
00516
00517 using namespace pilot;
00518 using namespace art_msgs;
00519 pstate_msg_.target.steering_angle = clamp(-ArtVehicle::max_steer_radians,
00520 pstate_msg_.target.steering_angle,
00521 ArtVehicle::max_steer_radians);
00522 }
00523
00525 int main(int argc, char** argv)
00526 {
00527 ros::init(argc, argv, "pilot");
00528 ros::NodeHandle node;
00529
00530 PilotNode pilot(node);
00531 pilot.spin();
00532
00533 return 0;
00534 }