• ROS+Gazebo中红绿黄交通灯如何实现?


    红灯:

    绿灯:

    黄灯:


    交通灯+车道识别,是最简单的自动驾驶仿真。


    参考代码如下:

    1. #include "GazeboTrafficLight.hpp"
    2. namespace gazebo {
    3. GazeboTrafficLight::GazeboTrafficLight() {
    4. sequence_timestamp_ = 0.0;
    5. }
    6. void GazeboTrafficLight::Load(physics::ModelPtr model, sdf::ElementPtr sdf) {
    7. ROS_INFO_STREAM("Loaded traffic light plugin for model: " << model->GetName());
    8. std::vector<geometry_msgs::TransformStamped> traffic_light_transforms;
    9. for (auto model_link : model->GetLinks()) {
    10. if (model_link->GetName().find("light_fixture") != std::string::npos) {
    11. geometry_msgs::TransformStamped new_light_transform;
    12. new_light_transform.header.frame_id = "world";
    13. new_light_transform.child_frame_id = parseLinkName(model_link->GetName());
    14. new_light_transform.transform.translation.x = model_link->WorldPose().Pos().X();
    15. new_light_transform.transform.translation.y = model_link->WorldPose().Pos().Y();
    16. new_light_transform.transform.translation.z = model_link->WorldPose().Pos().Z();
    17. new_light_transform.transform.rotation.w = model_link->WorldPose().Rot().W();
    18. new_light_transform.transform.rotation.x = model_link->WorldPose().Rot().X();
    19. new_light_transform.transform.rotation.y = model_link->WorldPose().Rot().Y();
    20. new_light_transform.transform.rotation.z = model_link->WorldPose().Rot().Z();
    21. traffic_light_transforms.push_back(new_light_transform);
    22. }
    23. }
    24. if (traffic_light_transforms.size() > 0) {
    25. broadcaster_.sendTransform(traffic_light_transforms);
    26. }
    27. for (auto model_joint : model->GetJoints()) {
    28. if (model_joint->GetName().find("switch") == std::string::npos) {
    29. continue;
    30. }
    31. std::string traffic_light_name;
    32. std::string joint_name;
    33. parseJointName(model_joint->GetName(), traffic_light_name, joint_name);
    34. if (joint_name.find("red") != std::string::npos) {
    35. traffic_lights_[traffic_light_name][RED] = model_joint;
    36. } else if (joint_name.find("yellow") != std::string::npos) {
    37. traffic_lights_[traffic_light_name][YELLOW] = model_joint;
    38. } else if (joint_name.find("green") != std::string::npos) {
    39. traffic_lights_[traffic_light_name][GREEN] = model_joint;
    40. }
    41. }
    42. n_.reset(new ros::NodeHandle(model->GetName()));
    43. light_timer_ = n_->createTimer(ros::Duration(0.1), &GazeboTrafficLight::timerCb, this);
    44. srv_.reset(new dynamic_reconfigure::Server<gazebo_traffic_light::GazeboTrafficLightConfig>(*n_));
    45. srv_->setCallback(boost::bind(&GazeboTrafficLight::reconfig, this, _1, _2));
    46. XmlRpc::XmlRpcValue sequence_list;
    47. if (n_->getParam("light_sequence", sequence_list)) {
    48. for (int i = 0; i < sequence_list.size(); i++) {
    49. XmlRpc::XmlRpcValue param_dict_list = sequence_list[i];
    50. LightSequenceEntry new_entry;
    51. bool parsable = true;
    52. if (param_dict_list["color"].getType() != XmlRpc::XmlRpcValue::TypeInvalid) {
    53. if (param_dict_list["color"].getType() == XmlRpc::XmlRpcValue::TypeString) {
    54. std::string color = param_dict_list["color"];
    55. if (color == "green") {
    56. new_entry.color = LightColor::GREEN;
    57. } else if (color == "yellow") {
    58. new_entry.color = LightColor::YELLOW;
    59. } else { // red
    60. new_entry.color = LightColor::RED;
    61. }
    62. } else {
    63. parsable = false;
    64. ROS_ERROR("Color attribute is not a string!");
    65. }
    66. }
    67. if (param_dict_list["duration"].getType() != XmlRpc::XmlRpcValue::TypeInvalid) {
    68. if (param_dict_list["duration"].getType() == XmlRpc::XmlRpcValue::TypeInt) {
    69. int temp_val = param_dict_list["duration"];
    70. new_entry.duration = (double)temp_val;
    71. } else if (param_dict_list["duration"].getType() == XmlRpc::XmlRpcValue::TypeDouble) {
    72. new_entry.duration = param_dict_list["duration"];
    73. } else {
    74. parsable = false;
    75. ROS_ERROR("Duration attribute is not a numeric type!");
    76. }
    77. }
    78. if (param_dict_list["flashing"].getType() != XmlRpc::XmlRpcValue::TypeInvalid) {
    79. if (param_dict_list["flashing"].getType() == XmlRpc::XmlRpcValue::TypeBoolean) {
    80. new_entry.flashing = param_dict_list["flashing"];
    81. } else {
    82. parsable = false;
    83. ROS_ERROR("Flashing attribute is not a boolean type!");
    84. }
    85. }
    86. if (parsable) {
    87. light_sequence_.push_back(new_entry);
    88. }
    89. }
    90. } else {
    91. ROS_INFO_STREAM("light_sequence parameter not found for model " << model->GetName() << "... Using default");
    92. light_sequence_.push_back(LightSequenceEntry(LightColor::GREEN, 4.0, false));
    93. light_sequence_.push_back(LightSequenceEntry(LightColor::YELLOW, 2.0, false));
    94. light_sequence_.push_back(LightSequenceEntry(LightColor::RED, 6.0, false));
    95. }
    96. computeCycleTime();
    97. }
    98. void GazeboTrafficLight::parseJointName(const std::string& input_str, std::string& traffic_light_name, std::string& joint_name) {
    99. std::string s = input_str;
    100. size_t pos = s.rfind("::");
    101. if (pos == std::string::npos) {
    102. traffic_light_name = "gazebo_traffic_light";
    103. joint_name = s;
    104. } else {
    105. traffic_light_name = s.substr(0, pos);
    106. joint_name = s.substr(pos + 2);
    107. }
    108. }
    109. std::string GazeboTrafficLight::parseLinkName(const std::string& input_str) {
    110. std::string output;
    111. std::string s = input_str;
    112. int count = std::count(input_str.begin(), input_str.end(), ':') / 2;
    113. if (count == 0) {
    114. output = s;
    115. } else {
    116. int limit = std::max(1, count - 1);
    117. for (int i = 0; i < limit; i++) {
    118. size_t pos = s.find("::");
    119. output += (s.substr(0, pos) + "_");
    120. s = s.substr(pos + 2);
    121. }
    122. output = output.substr(0, output.length() - 1); // Remove trailing underscore
    123. }
    124. return output;
    125. }
    126. void GazeboTrafficLight::computeCycleTime() {
    127. cycle_time_ = 0.0;
    128. for (auto& stage : light_sequence_) {
    129. cycle_time_ += stage.duration;
    130. }
    131. }
    132. void GazeboTrafficLight::timerCb(const ros::TimerEvent& event) {
    133. for (auto light : traffic_lights_) {
    134. switch (cfg_.override) {
    135. case gazebo_traffic_light::GazeboTrafficLight_NO_FORCE:
    136. advanceSequence(light.first);
    137. break;
    138. case gazebo_traffic_light::GazeboTrafficLight_RED:
    139. setColor(light.first, LightColor::RED, false);
    140. break;
    141. case gazebo_traffic_light::GazeboTrafficLight_RED_FLASH:
    142. setColor(light.first, LightColor::RED, true);
    143. break;
    144. case gazebo_traffic_light::GazeboTrafficLight_YELLOW:
    145. setColor(light.first, LightColor::YELLOW, false);
    146. break;
    147. case gazebo_traffic_light::GazeboTrafficLight_YELLOW_FLASH:
    148. setColor(light.first, LightColor::YELLOW, true);
    149. break;
    150. case gazebo_traffic_light::GazeboTrafficLight_GREEN:
    151. setColor(light.first, LightColor::GREEN, false);
    152. break;
    153. case gazebo_traffic_light::GazeboTrafficLight_GREEN_FLASH:
    154. setColor(light.first, LightColor::GREEN, true);
    155. break;
    156. }
    157. }
    158. if (event.last_expected == ros::Time(0)) {
    159. return;
    160. }
    161. sequence_timestamp_ += (event.current_real - event.last_real).toSec();
    162. if (sequence_timestamp_ >= cycle_time_) {
    163. sequence_timestamp_ -= cycle_time_;
    164. }
    165. }
    166. void GazeboTrafficLight::advanceSequence(const std::string& traffic_light_name) {
    167. double time_thres = cycle_time_;
    168. for (auto it = light_sequence_.rbegin(); it != light_sequence_.rend(); ++it) {
    169. time_thres -= it->duration;
    170. if (sequence_timestamp_ >= time_thres) {
    171. setColor(traffic_light_name, it->color, it->flashing);
    172. break;
    173. }
    174. }
    175. }
    176. void GazeboTrafficLight::setColor(const std::string& traffic_light_name, LightColor color, bool flashing) {
    177. for (int i = LightColor::RED; i <= LightColor::GREEN; i++) {
    178. if ( (flashing && ( (int)(1.25 * sequence_timestamp_) % 2 )) || (i != color) ){
    179. traffic_lights_[traffic_light_name][i]->SetPosition(0, LIGHT_OFF_POS_);
    180. } else {
    181. traffic_lights_[traffic_light_name][i]->SetPosition(0, LIGHT_ON_POS_);
    182. }
    183. }
    184. }
    185. void GazeboTrafficLight::reconfig(gazebo_traffic_light::GazeboTrafficLightConfig& config, uint32_t level) {
    186. sequence_timestamp_ = 0.0;
    187. cfg_ = config;
    188. }
    189. void GazeboTrafficLight::Reset() {
    190. }
    191. GazeboTrafficLight::~GazeboTrafficLight() {
    192. n_->shutdown();
    193. }
    194. } // namespace gazebo

    如何实现红黄绿等使用主题控制呢?

    1. #! /usr/bin/env python
    2. PACKAGE='gazebo_traffic_light'
    3. from dynamic_reconfigure.msg import SensorLevels
    4. from dynamic_reconfigure.parameter_generator_catkin import *
    5. gen = ParameterGenerator()
    6. force_enum = gen.enum( [gen.const("NO_FORCE", int_t, -1, ""),
    7. gen.const("RED", int_t, 0, ""),
    8. gen.const("RED_FLASH", int_t, 1, ""),
    9. gen.const("YELLOW", int_t, 2, ""),
    10. gen.const("YELLOW_FLASH", int_t, 3, ""),
    11. gen.const("GREEN", int_t, 4, ""),
    12. gen.const("GREEN_FLASH", int_t, 5, ""),
    13. ], "Bypass programmed sequence and force light state")
    14. # Name Type Level Description Default Min Max
    15. gen.add("override", int_t, 0, "Force light into a certain state", -1, -1, 5, edit_method=force_enum)
    16. exit(gen.generate(PACKAGE, PACKAGE, "GazeboTrafficLight"))

    如下图所示,如何设置:


    /gazebo/auto_disable_bodies
    /gazebo/cfm
    /gazebo/contact_max_correcting_vel
    /gazebo/contact_surface_layer
    /gazebo/enable_ros_network
    /gazebo/erp
    /gazebo/gravity_x
    /gazebo/gravity_y
    /gazebo/gravity_z
    /gazebo/max_contacts
    /gazebo/max_update_rate
    /gazebo/sor_pgs_iters
    /gazebo/sor_pgs_precon_iters
    /gazebo/sor_pgs_rms_error_tol
    /gazebo/sor_pgs_w
    /gazebo/time_step
    /gazebo_traffic_light/override
    /rosdistro/gazebo/auto_disable_bodies
    /gazebo/cfm
    /gazebo/contact_max_correcting_vel
    /gazebo/contact_surface_layer
    /gazebo/enable_ros_network
    /gazebo/erp
    /gazebo/gravity_x
    /gazebo/gravity_y
    /gazebo/gravity_z
    /gazebo/max_contacts
    /gazebo/max_update_rate
    /gazebo/sor_pgs_iters
    /gazebo/sor_pgs_precon_iters
    /gazebo/sor_pgs_rms_error_tol
    /gazebo/sor_pgs_w
    /gazebo/time_step
    /gazebo_traffic_light/override
    /rosdistro
    /roslaunch/uris/host_ros__34939
    /rosversion
    /run_id
    /test_cantilevered_traffic_light/light_sequence
    /test_cantilevered_traffic_light/override
    /test_included_traffic_light/override
    /use_sim_time
     


  • 相关阅读:
    【FAQ】HarmonyOS SDK 闭源开放能力 —Map Kit
    写着简单跑着又快的数据库语言SPL
    java中需要加入依赖才能使用的注解
    短视频账号矩阵系统===4年技术源头打磨
    深陷盈利困境,“寒冬”中也要二次递表,北森上市迫切
    NOIP2023模拟2联测23 C. 负责
    mindspore出现memory is not enough!
    大数据面试题:MapReduce压缩方式
    有才有料有趣,聊聊技术Demo的二三事
    string的模拟实现
  • 原文地址:https://blog.csdn.net/ZhangRelay/article/details/125492648