[{"data":1,"prerenderedAt":3644},["ShallowReactive",2],{"wiki-page-/en-us/wiki/2023-12-30-ros2-tutorial/ch14-6-7-jian-pan-kong-zhi-jie-dian":3,"wiki-doc-items-/en-us/wiki/2023-12-30-ros2-tutorial/ch14-6-7-jian-pan-kong-zhi-jie-dian":3282,"language-switcher-data-/en-us/wiki/2023-12-30-ros2-tutorial/ch14-6-7-jian-pan-kong-zhi-jie-dian":3628,"wiki-i18n-paths-/en-us/wiki/2023-12-30-ros2-tutorial/ch14-6-7-jian-pan-kong-zhi-jie-dian":3643},{"id":4,"title":5,"body":6,"canonicalPath":3263,"chapter":3264,"chapterSort":3265,"date":3266,"description":56,"docI18nKey":3267,"docKey":3268,"docRoot":3269,"docTitle":3270,"extension":3271,"i18nKey":3272,"isBlogPost":3273,"isWikiDoc":87,"isWikiIndex":3273,"layout":3274,"legacyPath":3274,"locale":3275,"localeSlug":3276,"meta":3277,"navigation":87,"path":3263,"seo":3278,"sourcePath":3279,"sourceStem":3272,"stem":3280,"wikiDepth":63,"__hash__":3281},"content/_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch14-6-7-键盘控制节点.md","Keyboard control node",{"type":7,"value":8,"toc":3256},"minimark",[9,14,23,46,50,78,198,248,255,259,866,869,938,941,945,963,1098,1101,1105,1110,1147,1151,1157,1163,1169,1175,1180,1183,1505,1508,3252],[10,11,13],"h3",{"id":12},"introduction","Introduction",[15,16,17,18,22],"p",{},"To control the chassis using the ",[19,20,21],"code",{},"keyboard"," node in ROS2, we need to implement the following steps:",[24,25,26,34,40],"ol",{},[27,28,29,33],"li",{},[30,31,32],"strong",{},"Creating a ROS2 Package"," Create a new ROS2 package for implementing keyboard control functionality.",[27,35,36,39],{},[30,37,38],{},"Writing a Keyboard Control Node"," Write a C++ node that listens for keyboard input and publishes velocity commands.",[27,41,42,45],{},[30,43,44],{},"Communicating with the Mecanum Wheel Chassis"," Combine the published speed commands with chassis control.",[10,47,49],{"id":48},"twist-message-interface","Twist message interface",[51,52,57],"pre",{"className":53,"code":54,"language":55,"meta":56,"style":56},"language-bash shiki shiki-themes github-light github-dark","ros2 interface show geometry_msgs/msg/Twist\n","bash","",[19,58,59],{"__ignoreMap":56},[60,61,64,68,72,75],"span",{"class":62,"line":63},"line",1,[60,65,67],{"class":66},"sScJk","ros2",[60,69,71],{"class":70},"sZZnC"," interface",[60,73,74],{"class":70}," show",[60,76,77],{"class":70}," geometry_msgs/msg/Twist\n",[51,79,81],{"className":53,"code":80,"language":55,"meta":56,"style":56},"\n# This expresses velocity in free space broken into its linear and angular parts.\n\n# 该消息表示自由空间中的速度，分为线速度和角速度两部分。\n\nVector3  linear\n        float64 x  # 线速度的 x 分量（通常表示前后方向的速度）\n        float64 y  # 线速度的 y 分量（通常表示左右方向的速度）\n        float64 z  # 线速度的 z 分量（通常表示上下方向的速度）\n\nVector3  angular\n        float64 x  # 角速度的 x 分量（绕 x 轴的旋转速度）\n        float64 y  # 角速度的 y 分量（绕 y 轴的旋转速度）\n        float64 z  # 角速度的 z 分量（绕 z 轴的旋转速度）\n\n",[19,82,83,89,96,101,107,112,121,133,144,155,160,168,178,188],{"__ignoreMap":56},[60,84,85],{"class":62,"line":63},[60,86,88],{"emptyLinePlaceholder":87},true,"\n",[60,90,92],{"class":62,"line":91},2,[60,93,95],{"class":94},"sJ8bj","# This expresses velocity in free space broken into its linear and angular parts.\n",[60,97,99],{"class":62,"line":98},3,[60,100,88],{"emptyLinePlaceholder":87},[60,102,104],{"class":62,"line":103},4,[60,105,106],{"class":94},"# 该消息表示自由空间中的速度，分为线速度和角速度两部分。\n",[60,108,110],{"class":62,"line":109},5,[60,111,88],{"emptyLinePlaceholder":87},[60,113,115,118],{"class":62,"line":114},6,[60,116,117],{"class":66},"Vector3",[60,119,120],{"class":70},"  linear\n",[60,122,124,127,130],{"class":62,"line":123},7,[60,125,126],{"class":66},"        float64",[60,128,129],{"class":70}," x",[60,131,132],{"class":94},"  # 线速度的 x 分量（通常表示前后方向的速度）\n",[60,134,136,138,141],{"class":62,"line":135},8,[60,137,126],{"class":66},[60,139,140],{"class":70}," y",[60,142,143],{"class":94},"  # 线速度的 y 分量（通常表示左右方向的速度）\n",[60,145,147,149,152],{"class":62,"line":146},9,[60,148,126],{"class":66},[60,150,151],{"class":70}," z",[60,153,154],{"class":94},"  # 线速度的 z 分量（通常表示上下方向的速度）\n",[60,156,158],{"class":62,"line":157},10,[60,159,88],{"emptyLinePlaceholder":87},[60,161,163,165],{"class":62,"line":162},11,[60,164,117],{"class":66},[60,166,167],{"class":70},"  angular\n",[60,169,171,173,175],{"class":62,"line":170},12,[60,172,126],{"class":66},[60,174,129],{"class":70},[60,176,177],{"class":94},"  # 角速度的 x 分量（绕 x 轴的旋转速度）\n",[60,179,181,183,185],{"class":62,"line":180},13,[60,182,126],{"class":66},[60,184,140],{"class":70},[60,186,187],{"class":94},"  # 角速度的 y 分量（绕 y 轴的旋转速度）\n",[60,189,191,193,195],{"class":62,"line":190},14,[60,192,126],{"class":66},[60,194,151],{"class":70},[60,196,197],{"class":94},"  # 角速度的 z 分量（绕 z 轴的旋转速度）\n",[199,200,201,227],"ul",{},[27,202,203,206,207],{},[30,204,205],{},"Linear velocity",": Describes the speed of an object moving along a straight line in three-dimensional space. Typically used in mobile robots:",[199,208,209,215,221],{},[27,210,211,214],{},[19,212,213],{},"x"," indicates forward/backward movement.",[27,216,217,220],{},[19,218,219],{},"y"," indicates left-right translation.",[27,222,223,226],{},[19,224,225],{},"z"," is usually 0, because most ground robots only move on a flat plane.",[27,228,229,232,233],{},[30,230,231],{},"Angular velocity",": Describes the speed at which an object rotates around an axis in three-dimensional space. Typically in mobile robotics:",[199,234,235,240],{},[27,236,237,239],{},[19,238,225],{}," represents rotation around the vertical axis (clockwise/counterclockwise).",[27,241,242,244,245,247],{},[19,243,213],{}," and ",[19,246,219],{}," are usually 0, since most ground robots only need to rotate on a flat plane.",[15,249,250,251,254],{},"This message type is widely used to control robot motion, commonly referred to as DOF (Degrees of Freedom). By publishing to the ",[19,252,253],{},"/cmd_vel"," topic, it can provide motion commands to the robot.",[10,256,258],{"id":257},"publish-cmd_vel-to-the-microcontroller","Publish cmd_vel to the microcontroller",[51,260,264],{"className":261,"code":262,"language":263,"meta":56,"style":56},"language-cpp shiki shiki-themes github-light github-dark","//初始化串口消息订阅\nrclcpp::Subscription\u003Cgeometry_msgs::msg::Twist>::SharedPtr cmd_vel_sub_;\ncmd_vel_sub_ = this->create_subscription\u003Cgeometry_msgs::msg::Twist(\"cmd_vel\",10,std::bind(&Serial_Node::cmd_vel_sub_callback,this,std::placeholders::_1));\n\n  void cmd_vel_sub_callback(const geometry_msgs::msg::Twist &cmd_msg)\n  {\n    // bool bool_buffer[] = {1, 0, 1, 0};\n    // int8_t int8_buffer[] = {0x11,0x22};\n    // int16_t int16_buffer[] = {2000,6666};\n    // int32_t int32_buffer[] = {305419896};\n    fp32 fp32_buffer[] = {(fp32)cmd_msg.linear.x,(fp32)cmd_msg.linear.y,(fp32)cmd_msg.linear.z,\n                          (fp32)cmd_msg.angular.x,(fp32)cmd_msg.angular.y,(fp32)cmd_msg.angular.z};\n\n    //由于ROS2中node为局部变量，所以只能在node中调用send函数，所以Serial_Transmit只负责处理data_buffer。\n    serial_pack_.tx.Data_Pack(0x01, \n                                 nullptr, 0,\n                                 nullptr, 0,\n                                 nullptr, 0,\n                                 nullptr, 0,\n                                 fp32_buffer, sizeof(fp32_buffer) / sizeof(fp32));\n\n    auto port = serial_driver_->port();\n\n    try\n    {\n      size_t bytes_size = port->send(data_buffer);\n      // RCLCPP_INFO(this->get_logger(), \"Transmitted: \");\n      // for (size_t i = 0; i \u003C data_buffer.size(); ++i) \n      // {\n        // RCLCPP_INFO(this->get_logger(), \"0x%02X \", data_buffer[i]);  //以十六进制格式打印每个字节\n      // }\n      RCLCPP_INFO(this->get_logger(), \"平动XYZ：%.6f,%.6f,%.6f\", fp32_buffer[0],fp32_buffer[1],fp32_buffer[2]);\n      RCLCPP_INFO(this->get_logger(), \"转动XYZ：%.6f,%.6f,%.6f\", fp32_buffer[3],fp32_buffer[4],fp32_buffer[5]);\n      RCLCPP_INFO(this->get_logger(), \"(%ld bytes)\", bytes_size);\n      // (void)bytes_size;\n    }\n    catch(const std::exception &ex)\n    {\n      RCLCPP_ERROR(this->get_logger(), \"Error Transmiting from serial port:%s\",ex.what());\n    }\n  }\n};\n","cpp",[19,265,266,271,302,378,382,416,421,426,431,436,441,451,456,460,465,485,500,511,522,533,554,559,579,584,590,596,616,622,628,634,643,649,704,751,778,784,790,811,816,849,854,860],{"__ignoreMap":56},[60,267,268],{"class":62,"line":63},[60,269,270],{"class":94},"//初始化串口消息订阅\n",[60,272,273,276,280,283,286,289,291,294,296,299],{"class":62,"line":91},[60,274,275],{"class":66},"rclcpp",[60,277,279],{"class":278},"sVt8B","::",[60,281,282],{"class":66},"Subscription",[60,284,285],{"class":278},"\u003C",[60,287,288],{"class":66},"geometry_msgs",[60,290,279],{"class":278},[60,292,293],{"class":66},"msg",[60,295,279],{"class":278},[60,297,298],{"class":66},"Twist",[60,300,301],{"class":278},">::SharedPtr cmd_vel_sub_;\n",[60,303,304,307,311,315,318,320,322,324,326,328,330,333,336,339,342,344,347,349,352,354,357,360,363,366,368,370,372,375],{"class":62,"line":98},[60,305,306],{"class":278},"cmd_vel_sub_ ",[60,308,310],{"class":309},"szBVR","=",[60,312,314],{"class":313},"sj4cs"," this",[60,316,317],{"class":278},"->create_subscription",[60,319,285],{"class":309},[60,321,288],{"class":66},[60,323,279],{"class":278},[60,325,293],{"class":66},[60,327,279],{"class":278},[60,329,298],{"class":66},[60,331,332],{"class":278},"(",[60,334,335],{"class":70},"\"cmd_vel\"",[60,337,338],{"class":278},",",[60,340,341],{"class":313},"10",[60,343,338],{"class":278},[60,345,346],{"class":66},"std",[60,348,279],{"class":278},[60,350,351],{"class":66},"bind",[60,353,332],{"class":278},[60,355,356],{"class":309},"&",[60,358,359],{"class":66},"Serial_Node",[60,361,362],{"class":278},"::cmd_vel_sub_callback,",[60,364,365],{"class":313},"this",[60,367,338],{"class":278},[60,369,346],{"class":66},[60,371,279],{"class":278},[60,373,374],{"class":66},"placeholders",[60,376,377],{"class":278},"::_1));\n",[60,379,380],{"class":62,"line":103},[60,381,88],{"emptyLinePlaceholder":87},[60,383,384,387,390,392,395,398,400,402,404,406,409,413],{"class":62,"line":109},[60,385,386],{"class":309},"  void",[60,388,389],{"class":66}," cmd_vel_sub_callback",[60,391,332],{"class":278},[60,393,394],{"class":309},"const",[60,396,397],{"class":66}," geometry_msgs",[60,399,279],{"class":278},[60,401,293],{"class":66},[60,403,279],{"class":278},[60,405,298],{"class":66},[60,407,408],{"class":309}," &",[60,410,412],{"class":411},"s4XuR","cmd_msg",[60,414,415],{"class":278},")\n",[60,417,418],{"class":62,"line":114},[60,419,420],{"class":278},"  {\n",[60,422,423],{"class":62,"line":123},[60,424,425],{"class":94},"    // bool bool_buffer[] = {1, 0, 1, 0};\n",[60,427,428],{"class":62,"line":135},[60,429,430],{"class":94},"    // int8_t int8_buffer[] = {0x11,0x22};\n",[60,432,433],{"class":62,"line":146},[60,434,435],{"class":94},"    // int16_t int16_buffer[] = {2000,6666};\n",[60,437,438],{"class":62,"line":157},[60,439,440],{"class":94},"    // int32_t int32_buffer[] = {305419896};\n",[60,442,443,446,448],{"class":62,"line":162},[60,444,445],{"class":278},"    fp32 fp32_buffer[] ",[60,447,310],{"class":309},[60,449,450],{"class":278}," {(fp32)cmd_msg.linear.x,(fp32)cmd_msg.linear.y,(fp32)cmd_msg.linear.z,\n",[60,452,453],{"class":62,"line":170},[60,454,455],{"class":278},"                          (fp32)cmd_msg.angular.x,(fp32)cmd_msg.angular.y,(fp32)cmd_msg.angular.z};\n",[60,457,458],{"class":62,"line":180},[60,459,88],{"emptyLinePlaceholder":87},[60,461,462],{"class":62,"line":190},[60,463,464],{"class":94},"    //由于ROS2中node为局部变量，所以只能在node中调用send函数，所以Serial_Transmit只负责处理data_buffer。\n",[60,466,468,471,474,476,479,482],{"class":62,"line":467},15,[60,469,470],{"class":278},"    serial_pack_.tx.",[60,472,473],{"class":66},"Data_Pack",[60,475,332],{"class":278},[60,477,478],{"class":309},"0x",[60,480,481],{"class":313},"01",[60,483,484],{"class":278},", \n",[60,486,488,491,494,497],{"class":62,"line":487},16,[60,489,490],{"class":313},"                                 nullptr",[60,492,493],{"class":278},", ",[60,495,496],{"class":313},"0",[60,498,499],{"class":278},",\n",[60,501,503,505,507,509],{"class":62,"line":502},17,[60,504,490],{"class":313},[60,506,493],{"class":278},[60,508,496],{"class":313},[60,510,499],{"class":278},[60,512,514,516,518,520],{"class":62,"line":513},18,[60,515,490],{"class":313},[60,517,493],{"class":278},[60,519,496],{"class":313},[60,521,499],{"class":278},[60,523,525,527,529,531],{"class":62,"line":524},19,[60,526,490],{"class":313},[60,528,493],{"class":278},[60,530,496],{"class":313},[60,532,499],{"class":278},[60,534,536,539,542,545,548,551],{"class":62,"line":535},20,[60,537,538],{"class":278},"                                 fp32_buffer, ",[60,540,541],{"class":309},"sizeof",[60,543,544],{"class":278},"(fp32_buffer) ",[60,546,547],{"class":309},"/",[60,549,550],{"class":309}," sizeof",[60,552,553],{"class":278},"(fp32));\n",[60,555,557],{"class":62,"line":556},21,[60,558,88],{"emptyLinePlaceholder":87},[60,560,562,565,568,570,573,576],{"class":62,"line":561},22,[60,563,564],{"class":309},"    auto",[60,566,567],{"class":278}," port ",[60,569,310],{"class":309},[60,571,572],{"class":278}," serial_driver_->",[60,574,575],{"class":66},"port",[60,577,578],{"class":278},"();\n",[60,580,582],{"class":62,"line":581},23,[60,583,88],{"emptyLinePlaceholder":87},[60,585,587],{"class":62,"line":586},24,[60,588,589],{"class":309},"    try\n",[60,591,593],{"class":62,"line":592},25,[60,594,595],{"class":278},"    {\n",[60,597,599,602,605,607,610,613],{"class":62,"line":598},26,[60,600,601],{"class":309},"      size_t",[60,603,604],{"class":278}," bytes_size ",[60,606,310],{"class":309},[60,608,609],{"class":278}," port->",[60,611,612],{"class":66},"send",[60,614,615],{"class":278},"(data_buffer);\n",[60,617,619],{"class":62,"line":618},27,[60,620,621],{"class":94},"      // RCLCPP_INFO(this->get_logger(), \"Transmitted: \");\n",[60,623,625],{"class":62,"line":624},28,[60,626,627],{"class":94},"      // for (size_t i = 0; i \u003C data_buffer.size(); ++i) \n",[60,629,631],{"class":62,"line":630},29,[60,632,633],{"class":94},"      // {\n",[60,635,637,640],{"class":62,"line":636},30,[60,638,639],{"class":94},"        // RCLCPP_INFO(this->get_logger(), \"0x%02X \", data_buffer[i]);",[60,641,642],{"class":94},"  //以十六进制格式打印每个字节\n",[60,644,646],{"class":62,"line":645},31,[60,647,648],{"class":94},"      // }\n",[60,650,652,655,657,659,662,665,668,671,674,676,678,680,682,685,688,690,693,696,698,701],{"class":62,"line":651},32,[60,653,654],{"class":66},"      RCLCPP_INFO",[60,656,332],{"class":278},[60,658,365],{"class":313},[60,660,661],{"class":278},"->",[60,663,664],{"class":66},"get_logger",[60,666,667],{"class":278},"(), ",[60,669,670],{"class":70},"\"平动XYZ：",[60,672,673],{"class":313},"%.6f",[60,675,338],{"class":70},[60,677,673],{"class":313},[60,679,338],{"class":70},[60,681,673],{"class":313},[60,683,684],{"class":70},"\"",[60,686,687],{"class":278},", fp32_buffer[",[60,689,496],{"class":313},[60,691,692],{"class":278},"],fp32_buffer[",[60,694,695],{"class":313},"1",[60,697,692],{"class":278},[60,699,700],{"class":313},"2",[60,702,703],{"class":278},"]);\n",[60,705,707,709,711,713,715,717,719,722,724,726,728,730,732,734,736,739,741,744,746,749],{"class":62,"line":706},33,[60,708,654],{"class":66},[60,710,332],{"class":278},[60,712,365],{"class":313},[60,714,661],{"class":278},[60,716,664],{"class":66},[60,718,667],{"class":278},[60,720,721],{"class":70},"\"转动XYZ：",[60,723,673],{"class":313},[60,725,338],{"class":70},[60,727,673],{"class":313},[60,729,338],{"class":70},[60,731,673],{"class":313},[60,733,684],{"class":70},[60,735,687],{"class":278},[60,737,738],{"class":313},"3",[60,740,692],{"class":278},[60,742,743],{"class":313},"4",[60,745,692],{"class":278},[60,747,748],{"class":313},"5",[60,750,703],{"class":278},[60,752,754,756,758,760,762,764,766,769,772,775],{"class":62,"line":753},34,[60,755,654],{"class":66},[60,757,332],{"class":278},[60,759,365],{"class":313},[60,761,661],{"class":278},[60,763,664],{"class":66},[60,765,667],{"class":278},[60,767,768],{"class":70},"\"(",[60,770,771],{"class":313},"%ld",[60,773,774],{"class":70}," bytes)\"",[60,776,777],{"class":278},", bytes_size);\n",[60,779,781],{"class":62,"line":780},35,[60,782,783],{"class":94},"      // (void)bytes_size;\n",[60,785,787],{"class":62,"line":786},36,[60,788,789],{"class":278},"    }\n",[60,791,793,796,798,800,803,806,808],{"class":62,"line":792},37,[60,794,795],{"class":309},"    catch",[60,797,332],{"class":278},[60,799,394],{"class":309},[60,801,802],{"class":66}," std",[60,804,805],{"class":278},"::exception ",[60,807,356],{"class":309},[60,809,810],{"class":278},"ex)\n",[60,812,814],{"class":62,"line":813},38,[60,815,595],{"class":278},[60,817,819,822,824,826,828,830,832,835,838,840,843,846],{"class":62,"line":818},39,[60,820,821],{"class":66},"      RCLCPP_ERROR",[60,823,332],{"class":278},[60,825,365],{"class":313},[60,827,661],{"class":278},[60,829,664],{"class":66},[60,831,667],{"class":278},[60,833,834],{"class":70},"\"Error Transmiting from serial port:",[60,836,837],{"class":313},"%s",[60,839,684],{"class":70},[60,841,842],{"class":278},",ex.",[60,844,845],{"class":66},"what",[60,847,848],{"class":278},"());\n",[60,850,852],{"class":62,"line":851},40,[60,853,789],{"class":278},[60,855,857],{"class":62,"line":856},41,[60,858,859],{"class":278},"  }\n",[60,861,863],{"class":62,"line":862},42,[60,864,865],{"class":278},"};\n",[15,867,868],{},"STM32 partial code:",[51,870,872],{"className":261,"code":871,"language":263,"meta":56,"style":56},"    case CHASSIS_ROS2_CMD: //ROS2接管模式\n        //单位就是m/s和rad/s\n        this->oriChassis.Speed.vx =   cmd_vel_.Linear.Y;\n        this->oriChassis.Speed.vy =   cmd_vel_.Linear.X;\n        this->oriChassis.Speed.vw = - cmd_vel_.Angular.Z;\n        break;\n",[19,873,874,885,890,903,915,930],{"__ignoreMap":56},[60,875,876,879,882],{"class":62,"line":63},[60,877,878],{"class":309},"    case",[60,880,881],{"class":278}," CHASSIS_ROS2_CMD:",[60,883,884],{"class":94}," //ROS2接管模式\n",[60,886,887],{"class":62,"line":91},[60,888,889],{"class":94},"        //单位就是m/s和rad/s\n",[60,891,892,895,898,900],{"class":62,"line":98},[60,893,894],{"class":313},"        this",[60,896,897],{"class":278},"->oriChassis.Speed.vx ",[60,899,310],{"class":309},[60,901,902],{"class":278},"   cmd_vel_.Linear.Y;\n",[60,904,905,907,910,912],{"class":62,"line":103},[60,906,894],{"class":313},[60,908,909],{"class":278},"->oriChassis.Speed.vy ",[60,911,310],{"class":309},[60,913,914],{"class":278},"   cmd_vel_.Linear.X;\n",[60,916,917,919,922,924,927],{"class":62,"line":109},[60,918,894],{"class":313},[60,920,921],{"class":278},"->oriChassis.Speed.vw ",[60,923,310],{"class":309},[60,925,926],{"class":309}," -",[60,928,929],{"class":278}," cmd_vel_.Angular.Z;\n",[60,931,932,935],{"class":62,"line":114},[60,933,934],{"class":309},"        break",[60,936,937],{"class":278},";\n",[15,939,940],{},"Since my STM32 uses Y as the chassis forward/backward direction, while ROS2 uses X as the chassis forward/backward direction, they are not fully aligned here.",[10,942,944],{"id":943},"official-node","Official Node",[51,946,948],{"className":53,"code":947,"language":55,"meta":56,"style":56},"ros2 run teleop_twist_keyboard teleop_twist_keyboard\n",[19,949,950],{"__ignoreMap":56},[60,951,952,954,957,960],{"class":62,"line":63},[60,953,67],{"class":66},[60,955,956],{"class":70}," run",[60,958,959],{"class":70}," teleop_twist_keyboard",[60,961,962],{"class":70}," teleop_twist_keyboard\n",[199,964,965,975,986,996,1005,1011,1022,1032,1043,1056,1072,1087],{},[27,966,967,970,971,974],{},[19,968,969],{},"i",": Move forward (increase linear velocity ",[19,972,973],{},"linear.x",")",[27,976,977,979,980,983,984,974],{},[19,978,338],{}," ",[30,981,982],{},"(comma)"," : Move backward (decrease linear velocity ",[19,985,973],{},[27,987,988,991,992,995],{},[19,989,990],{},"j",": Turn left (increase angular velocity ",[19,993,994],{},"angular.z",", counterclockwise)",[27,997,998,1001,1002,1004],{},[19,999,1000],{},"l",": Turn right (decrease angular velocity ",[19,1003,994],{},", clockwise)",[27,1006,1007,1010],{},[19,1008,1009],{},"k",": Emergency stop (zero out linear and angular velocities)",[27,1012,1013,1016,1017,1019,1020,974],{},[19,1014,1015],{},"u",": Turn forward left (combined motion: ",[19,1018,973],{}," + ",[19,1021,994],{},[27,1023,1024,1027,1028,1019,1030,974],{},[19,1025,1026],{},"o",": Turn forward and right (combined motion: ",[19,1029,973],{},[19,1031,994],{},[27,1033,1034,1037,1038,1019,1041,974],{},[19,1035,1036],{},"m",": Turn left backward (combined motion: ",[19,1039,1040],{},"-linear.x",[19,1042,994],{},[27,1044,1045,979,1048,1051,1052,1019,1054,974],{},[19,1046,1047],{},".",[30,1049,1050],{},"(period)"," : Turn right and backward (combined motion: ",[19,1053,1040],{},[19,1055,994],{},[27,1057,1058,1061,1063,1065,1066,1069,1070,974],{},[19,1059,1060],{},"w",[30,1062,547],{},[19,1064,213],{},": Increase/Decrease ",[30,1067,1068],{},"Linear Velocity"," (increment step for ",[19,1071,973],{},[27,1073,1074,1077,1079,1065,1082,1069,1085,974],{},[19,1075,1076],{},"a",[30,1078,547],{},[19,1080,1081],{},"d",[30,1083,1084],{},"angular velocity",[19,1086,994],{},[27,1088,1089,1092,1094,1097],{},[19,1090,1091],{},"s",[30,1093,547],{},[19,1095,1096],{},"S",": Emergency stop (sets linear and angular velocity to zero)",[15,1099,1100],{},"It is recommended to use the official nodes. Remember to reduce the step size before running.",[10,1102,1104],{"id":1103},"custom-node","Custom node",[1106,1107,1109],"h4",{"id":1108},"creating-a-function-package","Creating a function package",[51,1111,1113],{"className":53,"code":1112,"language":55,"meta":56,"style":56},"ros2 pkg create cyber_teleop_twist_keyboard --build-type ament_cmake --dependencies rclcpp geometry_msgs --node-name teleop_twist_keyboard\n",[19,1114,1115],{"__ignoreMap":56},[60,1116,1117,1119,1122,1125,1128,1131,1134,1137,1140,1142,1145],{"class":62,"line":63},[60,1118,67],{"class":66},[60,1120,1121],{"class":70}," pkg",[60,1123,1124],{"class":70}," create",[60,1126,1127],{"class":70}," cyber_teleop_twist_keyboard",[60,1129,1130],{"class":313}," --build-type",[60,1132,1133],{"class":70}," ament_cmake",[60,1135,1136],{"class":313}," --dependencies",[60,1138,1139],{"class":70}," rclcpp",[60,1141,397],{"class":70},[60,1143,1144],{"class":313}," --node-name",[60,1146,962],{"class":70},[1106,1148,1150],{"id":1149},"node-main-logic","Node main logic",[15,1152,1153,1156],{},[19,1154,1155],{},"w/s/a/d",": Controls the robot to move forward/backward/strafe left/strafe right.",[15,1158,1159,1162],{},[19,1160,1161],{},"q/e",": Controls the robot to rotate counterclockwise/clockwise.",[15,1164,1165,1168],{},[19,1166,1167],{},"i/,",": Adjust the linear velocity step size (acceleration/deceleration step size).",[15,1170,1171,1174],{},[19,1172,1173],{},"j/l",": Adjust the angular velocity step size (deceleration/acceleration step).",[15,1176,1177,1179],{},[19,1178,1009],{},": Stop all motion.",[15,1181,1182],{},"Below is a core function used for detecting key presses.",[51,1184,1186],{"className":261,"code":1185,"language":263,"meta":56,"style":56},"#include \u003Ctermios.h>\n#include \u003Cunistd.h>\n#include \u003Cfcntl.h>\n\n    //查键盘输入的函数，它不需要按回车就能返回键盘输入。它通过修改终端设置，使得可以直接获取按键的值。\n    int kbhit(void)\n    {\n      struct termios oldt, newt;\n      int ch;\n      int oldf;\n\n      tcgetattr(STDIN_FILENO, &oldt);        // 获取当前终端的设置\n      newt = oldt;\n      newt.c_lflag &= ~(ICANON | ECHO);       // 禁用缓冲模式和回显\n      newt.c_cc[VMIN] = 1;\n      newt.c_cc[VTIME] = 0;\n      tcsetattr(STDIN_FILENO, TCSANOW, &newt); // 设置新的终端设置\n\n      oldf = fcntl(STDIN_FILENO, F_GETFL, 0);\n      fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK); // 设置为非阻塞模式\n\n      ch = getchar(); // 获取字符\n      tcsetattr(STDIN_FILENO, TCSANOW, &oldt);   // 恢复终端设置\n      fcntl(STDIN_FILENO, F_SETFL, oldf);         // 恢复文件描述符设置\n\n      if(ch != EOF) { \n          ungetc(ch, stdin);  // 将字符放回标准输入流\n          return 1;           // 如果读取了字符，返回 1\n      }\n\n      return 0;   // 没有读取到字符\n    }\n",[19,1187,1188,1196,1203,1210,1214,1219,1234,1238,1249,1257,1264,1268,1284,1294,1317,1329,1341,1357,1361,1379,1395,1399,1415,1428,1438,1442,1456,1467,1480,1485,1489,1501],{"__ignoreMap":56},[60,1189,1190,1193],{"class":62,"line":63},[60,1191,1192],{"class":309},"#include",[60,1194,1195],{"class":70}," \u003Ctermios.h>\n",[60,1197,1198,1200],{"class":62,"line":91},[60,1199,1192],{"class":309},[60,1201,1202],{"class":70}," \u003Cunistd.h>\n",[60,1204,1205,1207],{"class":62,"line":98},[60,1206,1192],{"class":309},[60,1208,1209],{"class":70}," \u003Cfcntl.h>\n",[60,1211,1212],{"class":62,"line":103},[60,1213,88],{"emptyLinePlaceholder":87},[60,1215,1216],{"class":62,"line":109},[60,1217,1218],{"class":94},"    //查键盘输入的函数，它不需要按回车就能返回键盘输入。它通过修改终端设置，使得可以直接获取按键的值。\n",[60,1220,1221,1224,1227,1229,1232],{"class":62,"line":114},[60,1222,1223],{"class":309},"    int",[60,1225,1226],{"class":66}," kbhit",[60,1228,332],{"class":278},[60,1230,1231],{"class":309},"void",[60,1233,415],{"class":278},[60,1235,1236],{"class":62,"line":123},[60,1237,595],{"class":278},[60,1239,1240,1243,1246],{"class":62,"line":135},[60,1241,1242],{"class":309},"      struct",[60,1244,1245],{"class":66}," termios",[60,1247,1248],{"class":278}," oldt, newt;\n",[60,1250,1251,1254],{"class":62,"line":146},[60,1252,1253],{"class":309},"      int",[60,1255,1256],{"class":278}," ch;\n",[60,1258,1259,1261],{"class":62,"line":157},[60,1260,1253],{"class":309},[60,1262,1263],{"class":278}," oldf;\n",[60,1265,1266],{"class":62,"line":162},[60,1267,88],{"emptyLinePlaceholder":87},[60,1269,1270,1273,1276,1278,1281],{"class":62,"line":170},[60,1271,1272],{"class":66},"      tcgetattr",[60,1274,1275],{"class":278},"(STDIN_FILENO, ",[60,1277,356],{"class":309},[60,1279,1280],{"class":278},"oldt);",[60,1282,1283],{"class":94},"        // 获取当前终端的设置\n",[60,1285,1286,1289,1291],{"class":62,"line":180},[60,1287,1288],{"class":278},"      newt ",[60,1290,310],{"class":309},[60,1292,1293],{"class":278}," oldt;\n",[60,1295,1296,1299,1302,1305,1308,1311,1314],{"class":62,"line":190},[60,1297,1298],{"class":278},"      newt.c_lflag ",[60,1300,1301],{"class":309},"&=",[60,1303,1304],{"class":309}," ~",[60,1306,1307],{"class":278},"(ICANON ",[60,1309,1310],{"class":309},"|",[60,1312,1313],{"class":278}," ECHO);",[60,1315,1316],{"class":94},"       // 禁用缓冲模式和回显\n",[60,1318,1319,1322,1324,1327],{"class":62,"line":467},[60,1320,1321],{"class":278},"      newt.c_cc[VMIN] ",[60,1323,310],{"class":309},[60,1325,1326],{"class":313}," 1",[60,1328,937],{"class":278},[60,1330,1331,1334,1336,1339],{"class":62,"line":487},[60,1332,1333],{"class":278},"      newt.c_cc[VTIME] ",[60,1335,310],{"class":309},[60,1337,1338],{"class":313}," 0",[60,1340,937],{"class":278},[60,1342,1343,1346,1349,1351,1354],{"class":62,"line":502},[60,1344,1345],{"class":66},"      tcsetattr",[60,1347,1348],{"class":278},"(STDIN_FILENO, TCSANOW, ",[60,1350,356],{"class":309},[60,1352,1353],{"class":278},"newt);",[60,1355,1356],{"class":94}," // 设置新的终端设置\n",[60,1358,1359],{"class":62,"line":513},[60,1360,88],{"emptyLinePlaceholder":87},[60,1362,1363,1366,1368,1371,1374,1376],{"class":62,"line":524},[60,1364,1365],{"class":278},"      oldf ",[60,1367,310],{"class":309},[60,1369,1370],{"class":66}," fcntl",[60,1372,1373],{"class":278},"(STDIN_FILENO, F_GETFL, ",[60,1375,496],{"class":313},[60,1377,1378],{"class":278},");\n",[60,1380,1381,1384,1387,1389,1392],{"class":62,"line":535},[60,1382,1383],{"class":66},"      fcntl",[60,1385,1386],{"class":278},"(STDIN_FILENO, F_SETFL, oldf ",[60,1388,1310],{"class":309},[60,1390,1391],{"class":278}," O_NONBLOCK);",[60,1393,1394],{"class":94}," // 设置为非阻塞模式\n",[60,1396,1397],{"class":62,"line":556},[60,1398,88],{"emptyLinePlaceholder":87},[60,1400,1401,1404,1406,1409,1412],{"class":62,"line":561},[60,1402,1403],{"class":278},"      ch ",[60,1405,310],{"class":309},[60,1407,1408],{"class":66}," getchar",[60,1410,1411],{"class":278},"();",[60,1413,1414],{"class":94}," // 获取字符\n",[60,1416,1417,1419,1421,1423,1425],{"class":62,"line":581},[60,1418,1345],{"class":66},[60,1420,1348],{"class":278},[60,1422,356],{"class":309},[60,1424,1280],{"class":278},[60,1426,1427],{"class":94},"   // 恢复终端设置\n",[60,1429,1430,1432,1435],{"class":62,"line":586},[60,1431,1383],{"class":66},[60,1433,1434],{"class":278},"(STDIN_FILENO, F_SETFL, oldf);",[60,1436,1437],{"class":94},"         // 恢复文件描述符设置\n",[60,1439,1440],{"class":62,"line":592},[60,1441,88],{"emptyLinePlaceholder":87},[60,1443,1444,1447,1450,1453],{"class":62,"line":598},[60,1445,1446],{"class":309},"      if",[60,1448,1449],{"class":278},"(ch ",[60,1451,1452],{"class":309},"!=",[60,1454,1455],{"class":278}," EOF) { \n",[60,1457,1458,1461,1464],{"class":62,"line":618},[60,1459,1460],{"class":66},"          ungetc",[60,1462,1463],{"class":278},"(ch, stdin);",[60,1465,1466],{"class":94},"  // 将字符放回标准输入流\n",[60,1468,1469,1472,1474,1477],{"class":62,"line":624},[60,1470,1471],{"class":309},"          return",[60,1473,1326],{"class":313},[60,1475,1476],{"class":278},";",[60,1478,1479],{"class":94},"           // 如果读取了字符，返回 1\n",[60,1481,1482],{"class":62,"line":630},[60,1483,1484],{"class":278},"      }\n",[60,1486,1487],{"class":62,"line":636},[60,1488,88],{"emptyLinePlaceholder":87},[60,1490,1491,1494,1496,1498],{"class":62,"line":645},[60,1492,1493],{"class":309},"      return",[60,1495,1338],{"class":313},[60,1497,1476],{"class":278},[60,1499,1500],{"class":94},"   // 没有读取到字符\n",[60,1502,1503],{"class":62,"line":651},[60,1504,789],{"class":278},[15,1506,1507],{},"The following code has not been verified, use with caution. I directly used the official node and did not use a custom node.",[51,1509,1511],{"className":261,"code":1510,"language":263,"meta":56,"style":56},"#include \"rclcpp/rclcpp.hpp\"\n#include \"geometry_msgs/msg/twist.hpp\"\n#include \u003Cgeometry_msgs/msg/detail/twist__struct.hpp>\n#include \u003Ctermios.h>\n#include \u003Cunistd.h>\n#include \u003Cfcntl.h>\n#include \"cyber_teleop_twist_keyboard/struct_typedef.h\"\n\nclass TeleopTwistKeyboardNode: public rclcpp::Node\n{\n  public:\n    TeleopTwistKeyboardNode():Node(\"CyberTeleopTwistKeyboardNode_cpp\")\n    {\n      RCLCPP_INFO(this->get_logger(),\"TeleopTwistKeyboardNode Running!\");\n      RCLCPP_INFO(this->get_logger(),\"键盘控制机器人节点已启动！\");\n      // 创建一个发布者，类型是 geometry_msgs/msg/Twist，发布到 \"cmd_vel\" 话题\n      keyboard_control_pub_ = this->create_publisher\u003Cgeometry_msgs::msg::Twist>(\"cmd_vel\", 10);\n\n      // 定时器，周期性调用发布函数\n      keyboard_control_pub_timer_ = this->create_wall_timer(\n          std::chrono::milliseconds(100), \n          std::bind(&TeleopTwistKeyboardNode::cmd_vel_publish_timer_callback, this)\n        );\n\n    }\n\n  private:\n    rclcpp::Publisher\u003Cgeometry_msgs::msg::Twist>::SharedPtr keyboard_control_pub_;\n    rclcpp::TimerBase::SharedPtr keyboard_control_pub_timer_;\n\n    // 步长\n    fp64 linear_step_ = 0.1;\n    fp64 angular_step_ = 0.1;\n\n    // 当前线速度和角速度\n    fp64 linear_speed_ = 0.0;\n    fp64 angular_speed_ = 0.0;\n\n    // 最大速度限制\n    fp64 max_linear_speed_ = 0.5;\n    fp64 max_angular_speed_ = 0.2;\n\n    // 最小速度限制\n    fp64 min_linear_speed_ = 0.0;\n    fp64 min_angular_speed_ = 0.0;\n\n    geometry_msgs::msg::Twist cmd_msg;\n\n    //查键盘输入的函数，它不需要按回车就能返回键盘输入。它通过修改终端设置，使得可以直接获取按键的值。\n    int kbhit(void)\n    {\n      struct termios oldt, newt;\n      int ch;\n      int oldf;\n\n      tcgetattr(STDIN_FILENO, &oldt);        // 获取当前终端的设置\n      newt = oldt;\n      newt.c_lflag &= ~(ICANON | ECHO);       // 禁用缓冲模式和回显\n      newt.c_cc[VMIN] = 1;\n      newt.c_cc[VTIME] = 0;\n      tcsetattr(STDIN_FILENO, TCSANOW, &newt); // 设置新的终端设置\n\n      oldf = fcntl(STDIN_FILENO, F_GETFL, 0);\n      fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK); // 设置为非阻塞模式\n\n      ch = getchar(); // 获取字符\n      tcsetattr(STDIN_FILENO, TCSANOW, &oldt);   // 恢复终端设置\n      fcntl(STDIN_FILENO, F_SETFL, oldf);         // 恢复文件描述符设置\n\n      if(ch != EOF) { \n          ungetc(ch, stdin);  // 将字符放回标准输入流\n          return 1;           // 如果读取了字符，返回 1\n      }\n\n      return 0;   // 没有读取到字符\n    }\n\n  void cmd_vel_publish_timer_callback()\n  {\n\n    cmd_msg.linear.y = 0.0;\n    cmd_msg.linear.x = 0.0;\n    cmd_msg.angular.z = 0.0;\n\n    // 当有键盘输入时，处理它\n    if (kbhit()) \n    {\n      char key = getchar();  // 获取键盘输入的字符\n\n      if(key == EOF)\n      {\n        return;\n      }\n      RCLCPP_INFO(this->get_logger(),\"按下了:%c\",key);\n      // 根据按键决定机器人运动方向\n      switch(key)\n      {\n        case 'w': // 前进\n          cmd_msg.linear.y = linear_speed_;\n          cmd_msg.linear.x = 0.0;\n          cmd_msg.angular.z = 0.0;\n          break;\n        case 's': // 后退\n          cmd_msg.linear.y = - linear_speed_;\n          cmd_msg.linear.x = 0.0;\n          cmd_msg.angular.z = 0.0;\n          break;\n        case 'a': // 左平移\n          cmd_msg.linear.y = 0.0;\n          cmd_msg.linear.x = - linear_speed_;\n          cmd_msg.angular.z = 0.0;\n          break;\n        case 'd': // 右平移\n          cmd_msg.linear.y = 0.0;\n          cmd_msg.linear.x = linear_speed_;\n          cmd_msg.angular.z = 0.0;\n          break;\n        case 'q': // 逆时针旋转\n          cmd_msg.linear.y = 0.0;\n          cmd_msg.linear.x = 0.0;\n          cmd_msg.angular.z = - angular_speed_;\n          break;\n        case 'e': // 顺时针旋转\n          cmd_msg.angular.z = angular_speed_;\n          break;\n        case 'i': // 增加线速度\n          linear_speed_ = std::clamp(linear_speed_ + linear_step_, min_linear_speed_, max_linear_speed_);\n          RCLCPP_INFO(this->get_logger(), \"Linear increased to: %.2f\", linear_speed_);\n          break;\n        case ',': // 减小线速度\n          linear_speed_ = std::clamp(linear_speed_ - linear_step_, min_linear_speed_, max_linear_speed_);\n          RCLCPP_INFO(this->get_logger(), \"Linear decreased to: %.2f\", linear_speed_);\n          break;\n        case 'l': // 增加角速度\n          angular_speed_ = std::clamp(angular_speed_ + angular_step_, min_angular_speed_, max_angular_speed_);\n          RCLCPP_INFO(this->get_logger(), \"Angular increased to: %.2f\", angular_speed_);\n          break;\n        case 'j': // 减小角速度\n          angular_speed_ = std::clamp(angular_speed_ - angular_step_, min_angular_speed_, max_angular_speed_);\n          RCLCPP_INFO(this->get_logger(), \"Angular decreased to: %.2f\", angular_speed_);\n          break;\n        case 'k': // 停止\n          cmd_msg.linear.y = 0.0;\n          cmd_msg.linear.x = 0.0;\n          cmd_msg.angular.z = 0.0;\n          break;\n        default:\n          RCLCPP_WARN(this->get_logger(), \"Unknown key pressed!\");\n      }\n    }\n    keyboard_control_pub_->publish(cmd_msg);\n  }\n\n};\n\nint main(int argc, char ** argv)\n{\n  rclcpp::init(argc,argv);\n\n  auto node = std::make_shared\u003CTeleopTwistKeyboardNode>();\n\n  rclcpp::spin(node);\n\n  rclcpp::shutdown();\n  return 0;\n}\n",[19,1512,1513,1520,1527,1534,1540,1546,1552,1559,1563,1584,1589,1594,1612,1616,1636,1655,1660,1696,1700,1705,1722,1745,1767,1772,1776,1780,1784,1789,1814,1826,1830,1835,1847,1858,1862,1867,1879,1890,1894,1899,1911,1923,1927,1933,1945,1957,1962,1975,1980,1985,1998,2003,2012,2019,2026,2031,2044,2053,2070,2081,2092,2105,2110,2125,2138,2143,2156,2169,2178,2183,2194,2203,2214,2219,2224,2235,2240,2245,2256,2261,2266,2278,2290,2302,2307,2313,2328,2333,2351,2356,2370,2376,2384,2389,2415,2421,2430,2435,2450,2461,2473,2485,2493,2506,2517,2528,2539,2546,2559,2570,2581,2592,2599,2612,2623,2632,2643,2650,2663,2674,2685,2697,2704,2717,2726,2733,2746,2770,2797,2804,2817,2837,2861,2868,2881,2903,2928,2935,2948,2967,2991,2998,3011,3022,3033,3044,3051,3060,3081,3086,3091,3103,3108,3113,3118,3123,3152,3157,3171,3176,3201,3206,3219,3224,3236,3246],{"__ignoreMap":56},[60,1514,1515,1517],{"class":62,"line":63},[60,1516,1192],{"class":309},[60,1518,1519],{"class":70}," \"rclcpp/rclcpp.hpp\"\n",[60,1521,1522,1524],{"class":62,"line":91},[60,1523,1192],{"class":309},[60,1525,1526],{"class":70}," \"geometry_msgs/msg/twist.hpp\"\n",[60,1528,1529,1531],{"class":62,"line":98},[60,1530,1192],{"class":309},[60,1532,1533],{"class":70}," \u003Cgeometry_msgs/msg/detail/twist__struct.hpp>\n",[60,1535,1536,1538],{"class":62,"line":103},[60,1537,1192],{"class":309},[60,1539,1195],{"class":70},[60,1541,1542,1544],{"class":62,"line":109},[60,1543,1192],{"class":309},[60,1545,1202],{"class":70},[60,1547,1548,1550],{"class":62,"line":114},[60,1549,1192],{"class":309},[60,1551,1209],{"class":70},[60,1553,1554,1556],{"class":62,"line":123},[60,1555,1192],{"class":309},[60,1557,1558],{"class":70}," \"cyber_teleop_twist_keyboard/struct_typedef.h\"\n",[60,1560,1561],{"class":62,"line":135},[60,1562,88],{"emptyLinePlaceholder":87},[60,1564,1565,1568,1571,1574,1577,1579,1581],{"class":62,"line":146},[60,1566,1567],{"class":309},"class",[60,1569,1570],{"class":66}," TeleopTwistKeyboardNode",[60,1572,1573],{"class":278},": ",[60,1575,1576],{"class":309},"public",[60,1578,1139],{"class":66},[60,1580,279],{"class":278},[60,1582,1583],{"class":66},"Node\n",[60,1585,1586],{"class":62,"line":157},[60,1587,1588],{"class":278},"{\n",[60,1590,1591],{"class":62,"line":162},[60,1592,1593],{"class":309},"  public:\n",[60,1595,1596,1599,1602,1605,1607,1610],{"class":62,"line":170},[60,1597,1598],{"class":66},"    TeleopTwistKeyboardNode",[60,1600,1601],{"class":278},"():",[60,1603,1604],{"class":66},"Node",[60,1606,332],{"class":278},[60,1608,1609],{"class":70},"\"CyberTeleopTwistKeyboardNode_cpp\"",[60,1611,415],{"class":278},[60,1613,1614],{"class":62,"line":180},[60,1615,595],{"class":278},[60,1617,1618,1620,1622,1624,1626,1628,1631,1634],{"class":62,"line":190},[60,1619,654],{"class":66},[60,1621,332],{"class":278},[60,1623,365],{"class":313},[60,1625,661],{"class":278},[60,1627,664],{"class":66},[60,1629,1630],{"class":278},"(),",[60,1632,1633],{"class":70},"\"TeleopTwistKeyboardNode Running!\"",[60,1635,1378],{"class":278},[60,1637,1638,1640,1642,1644,1646,1648,1650,1653],{"class":62,"line":467},[60,1639,654],{"class":66},[60,1641,332],{"class":278},[60,1643,365],{"class":313},[60,1645,661],{"class":278},[60,1647,664],{"class":66},[60,1649,1630],{"class":278},[60,1651,1652],{"class":70},"\"键盘控制机器人节点已启动！\"",[60,1654,1378],{"class":278},[60,1656,1657],{"class":62,"line":487},[60,1658,1659],{"class":94},"      // 创建一个发布者，类型是 geometry_msgs/msg/Twist，发布到 \"cmd_vel\" 话题\n",[60,1661,1662,1665,1667,1669,1672,1674,1676,1678,1680,1683,1686,1688,1690,1692,1694],{"class":62,"line":502},[60,1663,1664],{"class":278},"      keyboard_control_pub_ ",[60,1666,310],{"class":309},[60,1668,314],{"class":313},[60,1670,1671],{"class":278},"->create_publisher",[60,1673,285],{"class":309},[60,1675,288],{"class":66},[60,1677,279],{"class":278},[60,1679,293],{"class":66},[60,1681,1682],{"class":278},"::Twist",[60,1684,1685],{"class":309},">",[60,1687,332],{"class":278},[60,1689,335],{"class":70},[60,1691,493],{"class":278},[60,1693,341],{"class":313},[60,1695,1378],{"class":278},[60,1697,1698],{"class":62,"line":513},[60,1699,88],{"emptyLinePlaceholder":87},[60,1701,1702],{"class":62,"line":524},[60,1703,1704],{"class":94},"      // 定时器，周期性调用发布函数\n",[60,1706,1707,1710,1712,1714,1716,1719],{"class":62,"line":535},[60,1708,1709],{"class":278},"      keyboard_control_pub_timer_ ",[60,1711,310],{"class":309},[60,1713,314],{"class":313},[60,1715,661],{"class":278},[60,1717,1718],{"class":66},"create_wall_timer",[60,1720,1721],{"class":278},"(\n",[60,1723,1724,1727,1729,1732,1734,1737,1739,1742],{"class":62,"line":556},[60,1725,1726],{"class":66},"          std",[60,1728,279],{"class":278},[60,1730,1731],{"class":66},"chrono",[60,1733,279],{"class":278},[60,1735,1736],{"class":66},"milliseconds",[60,1738,332],{"class":278},[60,1740,1741],{"class":313},"100",[60,1743,1744],{"class":278},"), \n",[60,1746,1747,1749,1751,1753,1755,1757,1760,1763,1765],{"class":62,"line":561},[60,1748,1726],{"class":66},[60,1750,279],{"class":278},[60,1752,351],{"class":66},[60,1754,332],{"class":278},[60,1756,356],{"class":309},[60,1758,1759],{"class":66},"TeleopTwistKeyboardNode",[60,1761,1762],{"class":278},"::cmd_vel_publish_timer_callback, ",[60,1764,365],{"class":313},[60,1766,415],{"class":278},[60,1768,1769],{"class":62,"line":581},[60,1770,1771],{"class":278},"        );\n",[60,1773,1774],{"class":62,"line":586},[60,1775,88],{"emptyLinePlaceholder":87},[60,1777,1778],{"class":62,"line":592},[60,1779,789],{"class":278},[60,1781,1782],{"class":62,"line":598},[60,1783,88],{"emptyLinePlaceholder":87},[60,1785,1786],{"class":62,"line":618},[60,1787,1788],{"class":309},"  private:\n",[60,1790,1791,1794,1796,1799,1801,1803,1805,1807,1809,1811],{"class":62,"line":624},[60,1792,1793],{"class":66},"    rclcpp",[60,1795,279],{"class":278},[60,1797,1798],{"class":66},"Publisher",[60,1800,285],{"class":278},[60,1802,288],{"class":66},[60,1804,279],{"class":278},[60,1806,293],{"class":66},[60,1808,279],{"class":278},[60,1810,298],{"class":66},[60,1812,1813],{"class":278},">::SharedPtr keyboard_control_pub_;\n",[60,1815,1816,1818,1820,1823],{"class":62,"line":630},[60,1817,1793],{"class":66},[60,1819,279],{"class":278},[60,1821,1822],{"class":66},"TimerBase",[60,1824,1825],{"class":278},"::SharedPtr keyboard_control_pub_timer_;\n",[60,1827,1828],{"class":62,"line":636},[60,1829,88],{"emptyLinePlaceholder":87},[60,1831,1832],{"class":62,"line":645},[60,1833,1834],{"class":94},"    // 步长\n",[60,1836,1837,1840,1842,1845],{"class":62,"line":651},[60,1838,1839],{"class":278},"    fp64 linear_step_ ",[60,1841,310],{"class":309},[60,1843,1844],{"class":313}," 0.1",[60,1846,937],{"class":278},[60,1848,1849,1852,1854,1856],{"class":62,"line":706},[60,1850,1851],{"class":278},"    fp64 angular_step_ ",[60,1853,310],{"class":309},[60,1855,1844],{"class":313},[60,1857,937],{"class":278},[60,1859,1860],{"class":62,"line":753},[60,1861,88],{"emptyLinePlaceholder":87},[60,1863,1864],{"class":62,"line":780},[60,1865,1866],{"class":94},"    // 当前线速度和角速度\n",[60,1868,1869,1872,1874,1877],{"class":62,"line":786},[60,1870,1871],{"class":278},"    fp64 linear_speed_ ",[60,1873,310],{"class":309},[60,1875,1876],{"class":313}," 0.0",[60,1878,937],{"class":278},[60,1880,1881,1884,1886,1888],{"class":62,"line":792},[60,1882,1883],{"class":278},"    fp64 angular_speed_ ",[60,1885,310],{"class":309},[60,1887,1876],{"class":313},[60,1889,937],{"class":278},[60,1891,1892],{"class":62,"line":813},[60,1893,88],{"emptyLinePlaceholder":87},[60,1895,1896],{"class":62,"line":818},[60,1897,1898],{"class":94},"    // 最大速度限制\n",[60,1900,1901,1904,1906,1909],{"class":62,"line":851},[60,1902,1903],{"class":278},"    fp64 max_linear_speed_ ",[60,1905,310],{"class":309},[60,1907,1908],{"class":313}," 0.5",[60,1910,937],{"class":278},[60,1912,1913,1916,1918,1921],{"class":62,"line":856},[60,1914,1915],{"class":278},"    fp64 max_angular_speed_ ",[60,1917,310],{"class":309},[60,1919,1920],{"class":313}," 0.2",[60,1922,937],{"class":278},[60,1924,1925],{"class":62,"line":862},[60,1926,88],{"emptyLinePlaceholder":87},[60,1928,1930],{"class":62,"line":1929},43,[60,1931,1932],{"class":94},"    // 最小速度限制\n",[60,1934,1936,1939,1941,1943],{"class":62,"line":1935},44,[60,1937,1938],{"class":278},"    fp64 min_linear_speed_ ",[60,1940,310],{"class":309},[60,1942,1876],{"class":313},[60,1944,937],{"class":278},[60,1946,1948,1951,1953,1955],{"class":62,"line":1947},45,[60,1949,1950],{"class":278},"    fp64 min_angular_speed_ ",[60,1952,310],{"class":309},[60,1954,1876],{"class":313},[60,1956,937],{"class":278},[60,1958,1960],{"class":62,"line":1959},46,[60,1961,88],{"emptyLinePlaceholder":87},[60,1963,1965,1968,1970,1972],{"class":62,"line":1964},47,[60,1966,1967],{"class":66},"    geometry_msgs",[60,1969,279],{"class":278},[60,1971,293],{"class":66},[60,1973,1974],{"class":278},"::Twist cmd_msg;\n",[60,1976,1978],{"class":62,"line":1977},48,[60,1979,88],{"emptyLinePlaceholder":87},[60,1981,1983],{"class":62,"line":1982},49,[60,1984,1218],{"class":94},[60,1986,1988,1990,1992,1994,1996],{"class":62,"line":1987},50,[60,1989,1223],{"class":309},[60,1991,1226],{"class":66},[60,1993,332],{"class":278},[60,1995,1231],{"class":309},[60,1997,415],{"class":278},[60,1999,2001],{"class":62,"line":2000},51,[60,2002,595],{"class":278},[60,2004,2006,2008,2010],{"class":62,"line":2005},52,[60,2007,1242],{"class":309},[60,2009,1245],{"class":66},[60,2011,1248],{"class":278},[60,2013,2015,2017],{"class":62,"line":2014},53,[60,2016,1253],{"class":309},[60,2018,1256],{"class":278},[60,2020,2022,2024],{"class":62,"line":2021},54,[60,2023,1253],{"class":309},[60,2025,1263],{"class":278},[60,2027,2029],{"class":62,"line":2028},55,[60,2030,88],{"emptyLinePlaceholder":87},[60,2032,2034,2036,2038,2040,2042],{"class":62,"line":2033},56,[60,2035,1272],{"class":66},[60,2037,1275],{"class":278},[60,2039,356],{"class":309},[60,2041,1280],{"class":278},[60,2043,1283],{"class":94},[60,2045,2047,2049,2051],{"class":62,"line":2046},57,[60,2048,1288],{"class":278},[60,2050,310],{"class":309},[60,2052,1293],{"class":278},[60,2054,2056,2058,2060,2062,2064,2066,2068],{"class":62,"line":2055},58,[60,2057,1298],{"class":278},[60,2059,1301],{"class":309},[60,2061,1304],{"class":309},[60,2063,1307],{"class":278},[60,2065,1310],{"class":309},[60,2067,1313],{"class":278},[60,2069,1316],{"class":94},[60,2071,2073,2075,2077,2079],{"class":62,"line":2072},59,[60,2074,1321],{"class":278},[60,2076,310],{"class":309},[60,2078,1326],{"class":313},[60,2080,937],{"class":278},[60,2082,2084,2086,2088,2090],{"class":62,"line":2083},60,[60,2085,1333],{"class":278},[60,2087,310],{"class":309},[60,2089,1338],{"class":313},[60,2091,937],{"class":278},[60,2093,2095,2097,2099,2101,2103],{"class":62,"line":2094},61,[60,2096,1345],{"class":66},[60,2098,1348],{"class":278},[60,2100,356],{"class":309},[60,2102,1353],{"class":278},[60,2104,1356],{"class":94},[60,2106,2108],{"class":62,"line":2107},62,[60,2109,88],{"emptyLinePlaceholder":87},[60,2111,2113,2115,2117,2119,2121,2123],{"class":62,"line":2112},63,[60,2114,1365],{"class":278},[60,2116,310],{"class":309},[60,2118,1370],{"class":66},[60,2120,1373],{"class":278},[60,2122,496],{"class":313},[60,2124,1378],{"class":278},[60,2126,2128,2130,2132,2134,2136],{"class":62,"line":2127},64,[60,2129,1383],{"class":66},[60,2131,1386],{"class":278},[60,2133,1310],{"class":309},[60,2135,1391],{"class":278},[60,2137,1394],{"class":94},[60,2139,2141],{"class":62,"line":2140},65,[60,2142,88],{"emptyLinePlaceholder":87},[60,2144,2146,2148,2150,2152,2154],{"class":62,"line":2145},66,[60,2147,1403],{"class":278},[60,2149,310],{"class":309},[60,2151,1408],{"class":66},[60,2153,1411],{"class":278},[60,2155,1414],{"class":94},[60,2157,2159,2161,2163,2165,2167],{"class":62,"line":2158},67,[60,2160,1345],{"class":66},[60,2162,1348],{"class":278},[60,2164,356],{"class":309},[60,2166,1280],{"class":278},[60,2168,1427],{"class":94},[60,2170,2172,2174,2176],{"class":62,"line":2171},68,[60,2173,1383],{"class":66},[60,2175,1434],{"class":278},[60,2177,1437],{"class":94},[60,2179,2181],{"class":62,"line":2180},69,[60,2182,88],{"emptyLinePlaceholder":87},[60,2184,2186,2188,2190,2192],{"class":62,"line":2185},70,[60,2187,1446],{"class":309},[60,2189,1449],{"class":278},[60,2191,1452],{"class":309},[60,2193,1455],{"class":278},[60,2195,2197,2199,2201],{"class":62,"line":2196},71,[60,2198,1460],{"class":66},[60,2200,1463],{"class":278},[60,2202,1466],{"class":94},[60,2204,2206,2208,2210,2212],{"class":62,"line":2205},72,[60,2207,1471],{"class":309},[60,2209,1326],{"class":313},[60,2211,1476],{"class":278},[60,2213,1479],{"class":94},[60,2215,2217],{"class":62,"line":2216},73,[60,2218,1484],{"class":278},[60,2220,2222],{"class":62,"line":2221},74,[60,2223,88],{"emptyLinePlaceholder":87},[60,2225,2227,2229,2231,2233],{"class":62,"line":2226},75,[60,2228,1493],{"class":309},[60,2230,1338],{"class":313},[60,2232,1476],{"class":278},[60,2234,1500],{"class":94},[60,2236,2238],{"class":62,"line":2237},76,[60,2239,789],{"class":278},[60,2241,2243],{"class":62,"line":2242},77,[60,2244,88],{"emptyLinePlaceholder":87},[60,2246,2248,2250,2253],{"class":62,"line":2247},78,[60,2249,386],{"class":309},[60,2251,2252],{"class":66}," cmd_vel_publish_timer_callback",[60,2254,2255],{"class":278},"()\n",[60,2257,2259],{"class":62,"line":2258},79,[60,2260,420],{"class":278},[60,2262,2264],{"class":62,"line":2263},80,[60,2265,88],{"emptyLinePlaceholder":87},[60,2267,2269,2272,2274,2276],{"class":62,"line":2268},81,[60,2270,2271],{"class":278},"    cmd_msg.linear.y ",[60,2273,310],{"class":309},[60,2275,1876],{"class":313},[60,2277,937],{"class":278},[60,2279,2281,2284,2286,2288],{"class":62,"line":2280},82,[60,2282,2283],{"class":278},"    cmd_msg.linear.x ",[60,2285,310],{"class":309},[60,2287,1876],{"class":313},[60,2289,937],{"class":278},[60,2291,2293,2296,2298,2300],{"class":62,"line":2292},83,[60,2294,2295],{"class":278},"    cmd_msg.angular.z ",[60,2297,310],{"class":309},[60,2299,1876],{"class":313},[60,2301,937],{"class":278},[60,2303,2305],{"class":62,"line":2304},84,[60,2306,88],{"emptyLinePlaceholder":87},[60,2308,2310],{"class":62,"line":2309},85,[60,2311,2312],{"class":94},"    // 当有键盘输入时，处理它\n",[60,2314,2316,2319,2322,2325],{"class":62,"line":2315},86,[60,2317,2318],{"class":309},"    if",[60,2320,2321],{"class":278}," (",[60,2323,2324],{"class":66},"kbhit",[60,2326,2327],{"class":278},"()) \n",[60,2329,2331],{"class":62,"line":2330},87,[60,2332,595],{"class":278},[60,2334,2336,2339,2342,2344,2346,2348],{"class":62,"line":2335},88,[60,2337,2338],{"class":309},"      char",[60,2340,2341],{"class":278}," key ",[60,2343,310],{"class":309},[60,2345,1408],{"class":66},[60,2347,1411],{"class":278},[60,2349,2350],{"class":94},"  // 获取键盘输入的字符\n",[60,2352,2354],{"class":62,"line":2353},89,[60,2355,88],{"emptyLinePlaceholder":87},[60,2357,2359,2361,2364,2367],{"class":62,"line":2358},90,[60,2360,1446],{"class":309},[60,2362,2363],{"class":278},"(key ",[60,2365,2366],{"class":309},"==",[60,2368,2369],{"class":278}," EOF)\n",[60,2371,2373],{"class":62,"line":2372},91,[60,2374,2375],{"class":278},"      {\n",[60,2377,2379,2382],{"class":62,"line":2378},92,[60,2380,2381],{"class":309},"        return",[60,2383,937],{"class":278},[60,2385,2387],{"class":62,"line":2386},93,[60,2388,1484],{"class":278},[60,2390,2392,2394,2396,2398,2400,2402,2404,2407,2410,2412],{"class":62,"line":2391},94,[60,2393,654],{"class":66},[60,2395,332],{"class":278},[60,2397,365],{"class":313},[60,2399,661],{"class":278},[60,2401,664],{"class":66},[60,2403,1630],{"class":278},[60,2405,2406],{"class":70},"\"按下了:",[60,2408,2409],{"class":313},"%c",[60,2411,684],{"class":70},[60,2413,2414],{"class":278},",key);\n",[60,2416,2418],{"class":62,"line":2417},95,[60,2419,2420],{"class":94},"      // 根据按键决定机器人运动方向\n",[60,2422,2424,2427],{"class":62,"line":2423},96,[60,2425,2426],{"class":309},"      switch",[60,2428,2429],{"class":278},"(key)\n",[60,2431,2433],{"class":62,"line":2432},97,[60,2434,2375],{"class":278},[60,2436,2438,2441,2444,2447],{"class":62,"line":2437},98,[60,2439,2440],{"class":309},"        case",[60,2442,2443],{"class":70}," 'w'",[60,2445,2446],{"class":278},":",[60,2448,2449],{"class":94}," // 前进\n",[60,2451,2453,2456,2458],{"class":62,"line":2452},99,[60,2454,2455],{"class":278},"          cmd_msg.linear.y ",[60,2457,310],{"class":309},[60,2459,2460],{"class":278}," linear_speed_;\n",[60,2462,2464,2467,2469,2471],{"class":62,"line":2463},100,[60,2465,2466],{"class":278},"          cmd_msg.linear.x ",[60,2468,310],{"class":309},[60,2470,1876],{"class":313},[60,2472,937],{"class":278},[60,2474,2476,2479,2481,2483],{"class":62,"line":2475},101,[60,2477,2478],{"class":278},"          cmd_msg.angular.z ",[60,2480,310],{"class":309},[60,2482,1876],{"class":313},[60,2484,937],{"class":278},[60,2486,2488,2491],{"class":62,"line":2487},102,[60,2489,2490],{"class":309},"          break",[60,2492,937],{"class":278},[60,2494,2496,2498,2501,2503],{"class":62,"line":2495},103,[60,2497,2440],{"class":309},[60,2499,2500],{"class":70}," 's'",[60,2502,2446],{"class":278},[60,2504,2505],{"class":94}," // 后退\n",[60,2507,2509,2511,2513,2515],{"class":62,"line":2508},104,[60,2510,2455],{"class":278},[60,2512,310],{"class":309},[60,2514,926],{"class":309},[60,2516,2460],{"class":278},[60,2518,2520,2522,2524,2526],{"class":62,"line":2519},105,[60,2521,2466],{"class":278},[60,2523,310],{"class":309},[60,2525,1876],{"class":313},[60,2527,937],{"class":278},[60,2529,2531,2533,2535,2537],{"class":62,"line":2530},106,[60,2532,2478],{"class":278},[60,2534,310],{"class":309},[60,2536,1876],{"class":313},[60,2538,937],{"class":278},[60,2540,2542,2544],{"class":62,"line":2541},107,[60,2543,2490],{"class":309},[60,2545,937],{"class":278},[60,2547,2549,2551,2554,2556],{"class":62,"line":2548},108,[60,2550,2440],{"class":309},[60,2552,2553],{"class":70}," 'a'",[60,2555,2446],{"class":278},[60,2557,2558],{"class":94}," // 左平移\n",[60,2560,2562,2564,2566,2568],{"class":62,"line":2561},109,[60,2563,2455],{"class":278},[60,2565,310],{"class":309},[60,2567,1876],{"class":313},[60,2569,937],{"class":278},[60,2571,2573,2575,2577,2579],{"class":62,"line":2572},110,[60,2574,2466],{"class":278},[60,2576,310],{"class":309},[60,2578,926],{"class":309},[60,2580,2460],{"class":278},[60,2582,2584,2586,2588,2590],{"class":62,"line":2583},111,[60,2585,2478],{"class":278},[60,2587,310],{"class":309},[60,2589,1876],{"class":313},[60,2591,937],{"class":278},[60,2593,2595,2597],{"class":62,"line":2594},112,[60,2596,2490],{"class":309},[60,2598,937],{"class":278},[60,2600,2602,2604,2607,2609],{"class":62,"line":2601},113,[60,2603,2440],{"class":309},[60,2605,2606],{"class":70}," 'd'",[60,2608,2446],{"class":278},[60,2610,2611],{"class":94}," // 右平移\n",[60,2613,2615,2617,2619,2621],{"class":62,"line":2614},114,[60,2616,2455],{"class":278},[60,2618,310],{"class":309},[60,2620,1876],{"class":313},[60,2622,937],{"class":278},[60,2624,2626,2628,2630],{"class":62,"line":2625},115,[60,2627,2466],{"class":278},[60,2629,310],{"class":309},[60,2631,2460],{"class":278},[60,2633,2635,2637,2639,2641],{"class":62,"line":2634},116,[60,2636,2478],{"class":278},[60,2638,310],{"class":309},[60,2640,1876],{"class":313},[60,2642,937],{"class":278},[60,2644,2646,2648],{"class":62,"line":2645},117,[60,2647,2490],{"class":309},[60,2649,937],{"class":278},[60,2651,2653,2655,2658,2660],{"class":62,"line":2652},118,[60,2654,2440],{"class":309},[60,2656,2657],{"class":70}," 'q'",[60,2659,2446],{"class":278},[60,2661,2662],{"class":94}," // 逆时针旋转\n",[60,2664,2666,2668,2670,2672],{"class":62,"line":2665},119,[60,2667,2455],{"class":278},[60,2669,310],{"class":309},[60,2671,1876],{"class":313},[60,2673,937],{"class":278},[60,2675,2677,2679,2681,2683],{"class":62,"line":2676},120,[60,2678,2466],{"class":278},[60,2680,310],{"class":309},[60,2682,1876],{"class":313},[60,2684,937],{"class":278},[60,2686,2688,2690,2692,2694],{"class":62,"line":2687},121,[60,2689,2478],{"class":278},[60,2691,310],{"class":309},[60,2693,926],{"class":309},[60,2695,2696],{"class":278}," angular_speed_;\n",[60,2698,2700,2702],{"class":62,"line":2699},122,[60,2701,2490],{"class":309},[60,2703,937],{"class":278},[60,2705,2707,2709,2712,2714],{"class":62,"line":2706},123,[60,2708,2440],{"class":309},[60,2710,2711],{"class":70}," 'e'",[60,2713,2446],{"class":278},[60,2715,2716],{"class":94}," // 顺时针旋转\n",[60,2718,2720,2722,2724],{"class":62,"line":2719},124,[60,2721,2478],{"class":278},[60,2723,310],{"class":309},[60,2725,2696],{"class":278},[60,2727,2729,2731],{"class":62,"line":2728},125,[60,2730,2490],{"class":309},[60,2732,937],{"class":278},[60,2734,2736,2738,2741,2743],{"class":62,"line":2735},126,[60,2737,2440],{"class":309},[60,2739,2740],{"class":70}," 'i'",[60,2742,2446],{"class":278},[60,2744,2745],{"class":94}," // 增加线速度\n",[60,2747,2749,2752,2754,2756,2758,2761,2764,2767],{"class":62,"line":2748},127,[60,2750,2751],{"class":278},"          linear_speed_ ",[60,2753,310],{"class":309},[60,2755,802],{"class":66},[60,2757,279],{"class":278},[60,2759,2760],{"class":66},"clamp",[60,2762,2763],{"class":278},"(linear_speed_ ",[60,2765,2766],{"class":309},"+",[60,2768,2769],{"class":278}," linear_step_, min_linear_speed_, max_linear_speed_);\n",[60,2771,2773,2776,2778,2780,2782,2784,2786,2789,2792,2794],{"class":62,"line":2772},128,[60,2774,2775],{"class":66},"          RCLCPP_INFO",[60,2777,332],{"class":278},[60,2779,365],{"class":313},[60,2781,661],{"class":278},[60,2783,664],{"class":66},[60,2785,667],{"class":278},[60,2787,2788],{"class":70},"\"Linear increased to: ",[60,2790,2791],{"class":313},"%.2f",[60,2793,684],{"class":70},[60,2795,2796],{"class":278},", linear_speed_);\n",[60,2798,2800,2802],{"class":62,"line":2799},129,[60,2801,2490],{"class":309},[60,2803,937],{"class":278},[60,2805,2807,2809,2812,2814],{"class":62,"line":2806},130,[60,2808,2440],{"class":309},[60,2810,2811],{"class":70}," ','",[60,2813,2446],{"class":278},[60,2815,2816],{"class":94}," // 减小线速度\n",[60,2818,2820,2822,2824,2826,2828,2830,2832,2835],{"class":62,"line":2819},131,[60,2821,2751],{"class":278},[60,2823,310],{"class":309},[60,2825,802],{"class":66},[60,2827,279],{"class":278},[60,2829,2760],{"class":66},[60,2831,2763],{"class":278},[60,2833,2834],{"class":309},"-",[60,2836,2769],{"class":278},[60,2838,2840,2842,2844,2846,2848,2850,2852,2855,2857,2859],{"class":62,"line":2839},132,[60,2841,2775],{"class":66},[60,2843,332],{"class":278},[60,2845,365],{"class":313},[60,2847,661],{"class":278},[60,2849,664],{"class":66},[60,2851,667],{"class":278},[60,2853,2854],{"class":70},"\"Linear decreased to: ",[60,2856,2791],{"class":313},[60,2858,684],{"class":70},[60,2860,2796],{"class":278},[60,2862,2864,2866],{"class":62,"line":2863},133,[60,2865,2490],{"class":309},[60,2867,937],{"class":278},[60,2869,2871,2873,2876,2878],{"class":62,"line":2870},134,[60,2872,2440],{"class":309},[60,2874,2875],{"class":70}," 'l'",[60,2877,2446],{"class":278},[60,2879,2880],{"class":94}," // 增加角速度\n",[60,2882,2884,2887,2889,2891,2893,2895,2898,2900],{"class":62,"line":2883},135,[60,2885,2886],{"class":278},"          angular_speed_ ",[60,2888,310],{"class":309},[60,2890,802],{"class":66},[60,2892,279],{"class":278},[60,2894,2760],{"class":66},[60,2896,2897],{"class":278},"(angular_speed_ ",[60,2899,2766],{"class":309},[60,2901,2902],{"class":278}," angular_step_, min_angular_speed_, max_angular_speed_);\n",[60,2904,2906,2908,2910,2912,2914,2916,2918,2921,2923,2925],{"class":62,"line":2905},136,[60,2907,2775],{"class":66},[60,2909,332],{"class":278},[60,2911,365],{"class":313},[60,2913,661],{"class":278},[60,2915,664],{"class":66},[60,2917,667],{"class":278},[60,2919,2920],{"class":70},"\"Angular increased to: ",[60,2922,2791],{"class":313},[60,2924,684],{"class":70},[60,2926,2927],{"class":278},", angular_speed_);\n",[60,2929,2931,2933],{"class":62,"line":2930},137,[60,2932,2490],{"class":309},[60,2934,937],{"class":278},[60,2936,2938,2940,2943,2945],{"class":62,"line":2937},138,[60,2939,2440],{"class":309},[60,2941,2942],{"class":70}," 'j'",[60,2944,2446],{"class":278},[60,2946,2947],{"class":94}," // 减小角速度\n",[60,2949,2951,2953,2955,2957,2959,2961,2963,2965],{"class":62,"line":2950},139,[60,2952,2886],{"class":278},[60,2954,310],{"class":309},[60,2956,802],{"class":66},[60,2958,279],{"class":278},[60,2960,2760],{"class":66},[60,2962,2897],{"class":278},[60,2964,2834],{"class":309},[60,2966,2902],{"class":278},[60,2968,2970,2972,2974,2976,2978,2980,2982,2985,2987,2989],{"class":62,"line":2969},140,[60,2971,2775],{"class":66},[60,2973,332],{"class":278},[60,2975,365],{"class":313},[60,2977,661],{"class":278},[60,2979,664],{"class":66},[60,2981,667],{"class":278},[60,2983,2984],{"class":70},"\"Angular decreased to: ",[60,2986,2791],{"class":313},[60,2988,684],{"class":70},[60,2990,2927],{"class":278},[60,2992,2994,2996],{"class":62,"line":2993},141,[60,2995,2490],{"class":309},[60,2997,937],{"class":278},[60,2999,3001,3003,3006,3008],{"class":62,"line":3000},142,[60,3002,2440],{"class":309},[60,3004,3005],{"class":70}," 'k'",[60,3007,2446],{"class":278},[60,3009,3010],{"class":94}," // 停止\n",[60,3012,3014,3016,3018,3020],{"class":62,"line":3013},143,[60,3015,2455],{"class":278},[60,3017,310],{"class":309},[60,3019,1876],{"class":313},[60,3021,937],{"class":278},[60,3023,3025,3027,3029,3031],{"class":62,"line":3024},144,[60,3026,2466],{"class":278},[60,3028,310],{"class":309},[60,3030,1876],{"class":313},[60,3032,937],{"class":278},[60,3034,3036,3038,3040,3042],{"class":62,"line":3035},145,[60,3037,2478],{"class":278},[60,3039,310],{"class":309},[60,3041,1876],{"class":313},[60,3043,937],{"class":278},[60,3045,3047,3049],{"class":62,"line":3046},146,[60,3048,2490],{"class":309},[60,3050,937],{"class":278},[60,3052,3054,3057],{"class":62,"line":3053},147,[60,3055,3056],{"class":309},"        default",[60,3058,3059],{"class":278},":\n",[60,3061,3063,3066,3068,3070,3072,3074,3076,3079],{"class":62,"line":3062},148,[60,3064,3065],{"class":66},"          RCLCPP_WARN",[60,3067,332],{"class":278},[60,3069,365],{"class":313},[60,3071,661],{"class":278},[60,3073,664],{"class":66},[60,3075,667],{"class":278},[60,3077,3078],{"class":70},"\"Unknown key pressed!\"",[60,3080,1378],{"class":278},[60,3082,3084],{"class":62,"line":3083},149,[60,3085,1484],{"class":278},[60,3087,3089],{"class":62,"line":3088},150,[60,3090,789],{"class":278},[60,3092,3094,3097,3100],{"class":62,"line":3093},151,[60,3095,3096],{"class":278},"    keyboard_control_pub_->",[60,3098,3099],{"class":66},"publish",[60,3101,3102],{"class":278},"(cmd_msg);\n",[60,3104,3106],{"class":62,"line":3105},152,[60,3107,859],{"class":278},[60,3109,3111],{"class":62,"line":3110},153,[60,3112,88],{"emptyLinePlaceholder":87},[60,3114,3116],{"class":62,"line":3115},154,[60,3117,865],{"class":278},[60,3119,3121],{"class":62,"line":3120},155,[60,3122,88],{"emptyLinePlaceholder":87},[60,3124,3126,3129,3132,3134,3136,3139,3141,3144,3147,3150],{"class":62,"line":3125},156,[60,3127,3128],{"class":309},"int",[60,3130,3131],{"class":66}," main",[60,3133,332],{"class":278},[60,3135,3128],{"class":309},[60,3137,3138],{"class":411}," argc",[60,3140,493],{"class":278},[60,3142,3143],{"class":309},"char",[60,3145,3146],{"class":309}," **",[60,3148,3149],{"class":411}," argv",[60,3151,415],{"class":278},[60,3153,3155],{"class":62,"line":3154},157,[60,3156,1588],{"class":278},[60,3158,3160,3163,3165,3168],{"class":62,"line":3159},158,[60,3161,3162],{"class":66},"  rclcpp",[60,3164,279],{"class":278},[60,3166,3167],{"class":66},"init",[60,3169,3170],{"class":278},"(argc,argv);\n",[60,3172,3174],{"class":62,"line":3173},159,[60,3175,88],{"emptyLinePlaceholder":87},[60,3177,3179,3182,3185,3187,3189,3191,3194,3196,3198],{"class":62,"line":3178},160,[60,3180,3181],{"class":309},"  auto",[60,3183,3184],{"class":278}," node ",[60,3186,310],{"class":309},[60,3188,802],{"class":66},[60,3190,279],{"class":278},[60,3192,3193],{"class":66},"make_shared",[60,3195,285],{"class":278},[60,3197,1759],{"class":66},[60,3199,3200],{"class":278},">();\n",[60,3202,3204],{"class":62,"line":3203},161,[60,3205,88],{"emptyLinePlaceholder":87},[60,3207,3209,3211,3213,3216],{"class":62,"line":3208},162,[60,3210,3162],{"class":66},[60,3212,279],{"class":278},[60,3214,3215],{"class":66},"spin",[60,3217,3218],{"class":278},"(node);\n",[60,3220,3222],{"class":62,"line":3221},163,[60,3223,88],{"emptyLinePlaceholder":87},[60,3225,3227,3229,3231,3234],{"class":62,"line":3226},164,[60,3228,3162],{"class":66},[60,3230,279],{"class":278},[60,3232,3233],{"class":66},"shutdown",[60,3235,578],{"class":278},[60,3237,3239,3242,3244],{"class":62,"line":3238},165,[60,3240,3241],{"class":309},"  return",[60,3243,1338],{"class":313},[60,3245,937],{"class":278},[60,3247,3249],{"class":62,"line":3248},166,[60,3250,3251],{"class":278},"}\n",[3253,3254,3255],"style",{},"html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}",{"title":56,"searchDepth":91,"depth":91,"links":3257},[3258,3259,3260,3261,3262],{"id":12,"depth":98,"text":13},{"id":48,"depth":98,"text":49},{"id":257,"depth":98,"text":258},{"id":943,"depth":98,"text":944},{"id":1103,"depth":98,"text":1104},"/en-us/wiki/2023-12-30-ros2-tutorial/ch14-6-7-jian-pan-kong-zhi-jie-dian","14.6.7",14060700,"2023-12-30","wiki/2023-12-30-ros2-tutorial","en-us:2023-12-30-ros2-tutorial","/en-us/wiki/2023-12-30-ros2-tutorial","Ros2 Tutorial","md","wiki/2023-12-30-ros2-tutorial/ch14-6-7-键盘控制节点",false,null,"en-US","en-us",{},{"title":5,"description":56},"/wiki/2023-12-30-ros2-tutorial/ch14-6-7-jian-pan-kong-zhi-jie-dian","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch14-6-7-键盘控制节点","rdtpRS8HTza8Isyh1q_rOGB0RcwR8IgWHnDDoUC-2Vc",[3283,3288,3293,3299,3305,3311,3317,3323,3329,3335,3341,3347,3353,3359,3365,3371,3377,3383,3388,3394,3399,3405,3411,3417,3423,3429,3435,3441,3447,3453,3459,3465,3471,3477,3483,3489,3490,3496,3502,3508,3514,3520,3526,3532,3538,3544,3550,3556,3562,3568,3574,3579,3585,3590,3595,3600,3606,3612,3618,3624],{"path":3284,"stem":3285,"title":3286,"date":3266,"chapter":695,"chapterSort":3287,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},"/en-us/wiki/2023-12-30-ros2-tutorial/ch1-ros2-jie-shao","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch1-ROS2介绍","Introduction to ROS2",1000000,{"path":3289,"stem":3290,"title":3291,"date":3266,"chapter":341,"chapterSort":3292,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},"/en-us/wiki/2023-12-30-ros2-tutorial/ch10-stage-ros2-fang-zhen-ping-tai","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch10-Stage_Ros2仿真平台","Stage_Ros2 Simulation Platform",10000000,{"path":3294,"stem":3295,"title":3296,"date":3266,"chapter":3297,"chapterSort":3298,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},"/en-us/wiki/2023-12-30-ros2-tutorial/ch11-1-gazeboclassic","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch11-1-GazeboClassic","Gezebo Classic","11.1",11010000,{"path":3300,"stem":3301,"title":3302,"date":3266,"chapter":3303,"chapterSort":3304,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},"/en-us/wiki/2023-12-30-ros2-tutorial/ch11-2-ignitiongazebo","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch11-2-IgnitionGazebo","Ignition Gazebo（Gazebo Fortress）","11.2",11020000,{"path":3306,"stem":3307,"title":3308,"date":3266,"chapter":3309,"chapterSort":3310,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},"/en-us/wiki/2023-12-30-ros2-tutorial/ch11-3-gazebosim","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch11-3-GazeboSim","Gz Sim（Gazebo Harmonic）","11.3",11030000,{"path":3312,"stem":3313,"title":3314,"date":3266,"chapter":3315,"chapterSort":3316,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},"/en-us/wiki/2023-12-30-ros2-tutorial/ch11-4-igngz2gzsim","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch11-4-Igngz2gzsim","Migrate Ign Gazebo to Gz Sim","11.4",11040000,{"path":3318,"stem":3319,"title":3320,"date":3266,"chapter":3321,"chapterSort":3322,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},"/en-us/wiki/2023-12-30-ros2-tutorial/ch11-gezebo-fang-zhen-ping-tai","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch11-Gezebo仿真平台","Gazebo simulation platform","11",11000000,{"path":3324,"stem":3325,"title":3326,"date":3266,"chapter":3327,"chapterSort":3328,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},"/en-us/wiki/2023-12-30-ros2-tutorial/ch12-1-humble-ban-ben","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch12-1-Humble版本","Humble Navigation Simulation","12.1",12010000,{"path":3330,"stem":3331,"title":3332,"date":3266,"chapter":3333,"chapterSort":3334,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},"/en-us/wiki/2023-12-30-ros2-tutorial/ch12-2-jazzy-ban-ben","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch12-2-Jazzy版本","Jazzy Navigation Simulation","12.2",12020000,{"path":3336,"stem":3337,"title":3338,"date":3266,"chapter":3339,"chapterSort":3340,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},"/en-us/wiki/2023-12-30-ros2-tutorial/ch12-3-humble2jazzy","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch12-3-Humble2Jazzy","Differences in Navigation between Humble and Jazzy","12.3",12030000,{"path":3342,"stem":3343,"title":3344,"date":3266,"chapter":3345,"chapterSort":3346,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},"/en-us/wiki/2023-12-30-ros2-tutorial/ch12-ji-qi-ren-dao-hang-navigation2-fang-zhen-pian","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch12-机器人导航Navigation2(仿真篇)","Robot Navigation with Navigation2 (Simulation)","12",12000000,{"path":3348,"stem":3349,"title":3350,"date":3266,"chapter":3351,"chapterSort":3352,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},"/en-us/wiki/2023-12-30-ros2-tutorial/ch13-1-1-boost-aiso","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch13-1-1-Boost.Aiso","Boost.Asio库","13.1.1",13010100,{"path":3354,"stem":3355,"title":3356,"date":3266,"chapter":3357,"chapterSort":3358,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},"/en-us/wiki/2023-12-30-ros2-tutorial/ch13-1-2-ros2-serial-driver","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch13-1-2-ros2_serial_driver","ROS2 Serial Driver Library","13.1.2",13010200,{"path":3360,"stem":3361,"title":3362,"date":3266,"chapter":3363,"chapterSort":3364,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},"/en-us/wiki/2023-12-30-ros2-tutorial/ch13-1-chuan-kou-tong-xin","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch13-1-串口通信","UART serial communication","13.1",13010000,{"path":3366,"stem":3367,"title":3368,"date":3266,"chapter":3369,"chapterSort":3370,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},"/en-us/wiki/2023-12-30-ros2-tutorial/ch13-2-1-socketcan","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch13-2-1-socketcan","SocketCAN","13.2.1",13020100,{"path":3372,"stem":3373,"title":3374,"date":3266,"chapter":3375,"chapterSort":3376,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},"/en-us/wiki/2023-12-30-ros2-tutorial/ch13-2-2-ros2-socketcan","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch13-2-2-ros2_socketcan","ROS2_SocketCAN","13.2.2",13020200,{"path":3378,"stem":3379,"title":3380,"date":3266,"chapter":3381,"chapterSort":3382,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},"/en-us/wiki/2023-12-30-ros2-tutorial/ch13-2-can-tong-xin","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch13-2-CAN通信","CAN communication","13.2",13020000,{"path":3384,"stem":3385,"title":3350,"date":3266,"chapter":3386,"chapterSort":3387,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},"/en-us/wiki/2023-12-30-ros2-tutorial/ch13-3-1-boost-aiso","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch13-3-1-Boost.Aiso","13.3.1",13030100,{"path":3389,"stem":3390,"title":3391,"date":3266,"chapter":3392,"chapterSort":3393,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},"/en-us/wiki/2023-12-30-ros2-tutorial/ch13-3-tcp-tong-xin","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch13-3-TCP通信","TCP communication","13.3",13030000,{"path":3395,"stem":3396,"title":3350,"date":3266,"chapter":3397,"chapterSort":3398,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},"/en-us/wiki/2023-12-30-ros2-tutorial/ch13-4-1-boost-aiso","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch13-4-1-Boost.Aiso","13.4.1",13040100,{"path":3400,"stem":3401,"title":3402,"date":3266,"chapter":3403,"chapterSort":3404,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},"/en-us/wiki/2023-12-30-ros2-tutorial/ch13-4-udp-tong-xin","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch13-4-UDP通信","UDP communication","13.4",13040000,{"path":3406,"stem":3407,"title":3408,"date":3266,"chapter":3409,"chapterSort":3410,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},"/en-us/wiki/2023-12-30-ros2-tutorial/ch13-linux-ying-jian-tong-xin","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch13-Linux硬件通信","Linux hardware communication","13",13000000,{"path":3412,"stem":3413,"title":3414,"date":3266,"chapter":3415,"chapterSort":3416,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},"/en-us/wiki/2023-12-30-ros2-tutorial/ch14-1-ji-qi-ren-zu-cheng","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch14-1-机器人组成","Robot Composition","14.1",14010000,{"path":3418,"stem":3419,"title":3420,"date":3266,"chapter":3421,"chapterSort":3422,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},"/en-us/wiki/2023-12-30-ros2-tutorial/ch14-2-1-yuan-cheng-kai-fa-ssh","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch14-2-1-远程开发SSH","Remote Development SSH","14.2.1",14020100,{"path":3424,"stem":3425,"title":3426,"date":3266,"chapter":3427,"chapterSort":3428,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},"/en-us/wiki/2023-12-30-ros2-tutorial/ch14-2-2-yuan-cheng-fang-wen-zhuo-mian","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch14-2-2-远程访问桌面","Remote Desktop Access","14.2.2",14020200,{"path":3430,"stem":3431,"title":3432,"date":3266,"chapter":3433,"chapterSort":3434,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},"/en-us/wiki/2023-12-30-ros2-tutorial/ch14-2-gong-kong-ji-zhi-yuan-cheng-kai-fa-huan-jing","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch14-2-工控机之远程开发环境","Remote Development Environment for Industrial PC","14.2",14020000,{"path":3436,"stem":3437,"title":3438,"date":3266,"chapter":3439,"chapterSort":3440,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},"/en-us/wiki/2023-12-30-ros2-tutorial/ch14-3-gong-kong-ji-zhi-wai-jie-usb-she-bei","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch14-3-工控机之外接USB设备","External USB Devices for the Industrial PC","14.3",14030000,{"path":3442,"stem":3443,"title":3444,"date":3266,"chapter":3445,"chapterSort":3446,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},"/en-us/wiki/2023-12-30-ros2-tutorial/ch14-4-fen-bu-shi-da-jian","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch14-4-分布式搭建","Distributed setup","14.4",14040000,{"path":3448,"stem":3449,"title":3450,"date":3266,"chapter":3451,"chapterSort":3452,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},"/en-us/wiki/2023-12-30-ros2-tutorial/ch14-5-you-hua-ri-zhi","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch14-5-优化日志","Optimize logs","14.5",14050000,{"path":3454,"stem":3455,"title":3456,"date":3266,"chapter":3457,"chapterSort":3458,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},"/en-us/wiki/2023-12-30-ros2-tutorial/ch14-6-1-li-cheng-ji-odom","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch14-6-1-里程计Odom","odometry","14.6.1",14060100,{"path":3460,"stem":3461,"title":3462,"date":3266,"chapter":3463,"chapterSort":3464,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},"/en-us/wiki/2023-12-30-ros2-tutorial/ch14-6-2-guan-xing-ji-imu","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch14-6-2-惯性计IMU","Inertial Measurement Unit (IMU)","14.6.2",14060200,{"path":3466,"stem":3467,"title":3468,"date":3266,"chapter":3469,"chapterSort":3470,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},"/en-us/wiki/2023-12-30-ros2-tutorial/ch14-6-3-ji-guang-lei-da-lidar","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch14-6-3-激光雷达LiDAR","LiDAR","14.6.3",14060300,{"path":3472,"stem":3473,"title":3474,"date":3266,"chapter":3475,"chapterSort":3476,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},"/en-us/wiki/2023-12-30-ros2-tutorial/ch14-6-4-xiang-ji-camera","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch14-6-4-相机Camera","Camera","14.6.4",14060400,{"path":3478,"stem":3479,"title":3480,"date":3266,"chapter":3481,"chapterSort":3482,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},"/en-us/wiki/2023-12-30-ros2-tutorial/ch14-6-5-quan-qiu-ding-wei-gnss","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch14-6-5-全球定位GNSS","Global Navigation Satellite System (GNSS)","14.6.5",14060500,{"path":3484,"stem":3485,"title":3486,"date":3266,"chapter":3487,"chapterSort":3488,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},"/en-us/wiki/2023-12-30-ros2-tutorial/ch14-6-6-shou-bing-joy","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch14-6-6-手柄joy","The query \"手柄JOY\" is a bit ambiguous. To help you better, could you please provide more details? For example:","14.6.6",14060600,{"path":3263,"stem":3280,"title":5,"date":3266,"chapter":3264,"chapterSort":3265,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},{"path":3491,"stem":3492,"title":3493,"date":3266,"chapter":3494,"chapterSort":3495,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},"/en-us/wiki/2023-12-30-ros2-tutorial/ch14-6-ying-jian-ping-tai","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch14-6-硬件平台","Hardware platform","14.6",14060000,{"path":3497,"stem":3498,"title":3499,"date":3266,"chapter":3500,"chapterSort":3501,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},"/en-us/wiki/2023-12-30-ros2-tutorial/ch14-7-zuo-biao-xi-yu-hua-ti-guan-xi","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch14-7-坐标系与话题关系","Coordinate System and Topic Relationship","14.7",14070000,{"path":3503,"stem":3504,"title":3505,"date":3266,"chapter":3506,"chapterSort":3507,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},"/en-us/wiki/2023-12-30-ros2-tutorial/ch14-8-1-1-lun-shi-li-cheng-ji-biao-ding","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch14-8-1-1-轮式里程计标定","Wheel odometry calibration","14.8.1.1",14080101,{"path":3509,"stem":3510,"title":3511,"date":3266,"chapter":3512,"chapterSort":3513,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},"/en-us/wiki/2023-12-30-ros2-tutorial/ch14-8-1-2-lun-shi-li-cheng-ji-yu-imu-rong-he","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch14-8-1-2-轮式里程计与IMU融合","Fusion of Wheel Odometry and IMU","14.8.1.2",14080102,{"path":3515,"stem":3516,"title":3517,"date":3266,"chapter":3518,"chapterSort":3519,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},"/en-us/wiki/2023-12-30-ros2-tutorial/ch14-8-1-lun-shi-li-cheng-ji-biao-ding-yu-rong-he","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch14-8-1-轮式里程计标定与融合","Wheel odometry calibration and fusion","14.8.1",14080100,{"path":3521,"stem":3522,"title":3523,"date":3266,"chapter":3524,"chapterSort":3525,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},"/en-us/wiki/2023-12-30-ros2-tutorial/ch14-8-2-ji-guang-lei-da-gong-ju","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch14-8-2-激光雷达工具","Lidar Tool","14.8.2",14080200,{"path":3527,"stem":3528,"title":3529,"date":3266,"chapter":3530,"chapterSort":3531,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},"/en-us/wiki/2023-12-30-ros2-tutorial/ch14-8-3-xiang-ji-shi-yong-jin-jie","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch14-8-3-相机使用进阶","Advanced Camera Usage","14.8.3",14080300,{"path":3533,"stem":3534,"title":3535,"date":3266,"chapter":3536,"chapterSort":3537,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},"/en-us/wiki/2023-12-30-ros2-tutorial/ch14-8-ying-jian-ping-tai-jin-jie","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch14-8-硬件平台进阶","Advanced Hardware Platform","14.8",14080000,{"path":3539,"stem":3540,"title":3541,"date":3266,"chapter":3542,"chapterSort":3543,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},"/en-us/wiki/2023-12-30-ros2-tutorial/ch14-ji-qi-ren-ying-jian","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch14-机器人硬件","Robot hardware","14",14000000,{"path":3545,"stem":3546,"title":3547,"date":3266,"chapter":3548,"chapterSort":3549,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},"/en-us/wiki/2023-12-30-ros2-tutorial/ch15-ros2-control","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch15-ROS2_Control","ROS2_Control","15",15000000,{"path":3551,"stem":3552,"title":3553,"date":3266,"chapter":3554,"chapterSort":3555,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},"/en-us/wiki/2023-12-30-ros2-tutorial/ch16-moveit2-gong-ye-ji-qi-ren-ji-xie-bi","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch16-Moveit2工业机器人机械臂","MoveIt2 industrial robot arm","16",16000000,{"path":3557,"stem":3558,"title":3559,"date":3266,"chapter":3560,"chapterSort":3561,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},"/en-us/wiki/2023-12-30-ros2-tutorial/ch17-ji-qi-ren-dao-hang-navigation2-shi-ti-pian","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch17-机器人导航Navigation2(实体篇)","Robot Navigation with Navigation2 (Physical Robot)","17",17000000,{"path":3563,"stem":3564,"title":3565,"date":3266,"chapter":3566,"chapterSort":3567,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},"/en-us/wiki/2023-12-30-ros2-tutorial/ch18-microros","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch18-MicroROS","MicroROS","18",18000000,{"path":3569,"stem":3570,"title":3571,"date":3266,"chapter":3572,"chapterSort":3573,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},"/en-us/wiki/2023-12-30-ros2-tutorial/ch19-webots-fang-zhen-ping-tai","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch19-Webots仿真平台","Webots simulation platform","19",19000000,{"path":3575,"stem":3576,"title":3577,"date":3266,"chapter":700,"chapterSort":3578,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},"/en-us/wiki/2023-12-30-ros2-tutorial/ch2-ru-men-cao-zuo","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch2-入门操作","Getting Started",2000000,{"path":3580,"stem":3581,"title":3582,"date":3266,"chapter":3583,"chapterSort":3584,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},"/en-us/wiki/2023-12-30-ros2-tutorial/ch20-opencv","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch20-OpenCV","OpenCV","20",20000000,{"path":3586,"stem":3587,"title":3588,"date":3266,"chapter":738,"chapterSort":3589,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},"/en-us/wiki/2023-12-30-ros2-tutorial/ch3-gong-zuo-kong-jian-yu-gong-neng-bao","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch3-工作空间与功能包","Workspace and Function Packages",3000000,{"path":3591,"stem":3592,"title":3593,"date":3266,"chapter":743,"chapterSort":3594,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},"/en-us/wiki/2023-12-30-ros2-tutorial/ch4-si-da-tong-xin","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch4-四大通信","Four Major Communications",4000000,{"path":3596,"stem":3597,"title":3598,"date":3266,"chapter":748,"chapterSort":3599,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},"/en-us/wiki/2023-12-30-ros2-tutorial/ch5-ros2-qi-ta-tong-xin-ji-zhi","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch5-ROS2其他通信机制","ROS2 Other Communication Mechanisms",5000000,{"path":3601,"stem":3602,"title":3603,"date":3266,"chapter":3604,"chapterSort":3605,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},"/en-us/wiki/2023-12-30-ros2-tutorial/ch6-launch","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch6-Launch","Launch","6",6000000,{"path":3607,"stem":3608,"title":3609,"date":3266,"chapter":3610,"chapterSort":3611,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},"/en-us/wiki/2023-12-30-ros2-tutorial/ch7-hui-su-rosbag2","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch7-回溯rosbag2","Replaying rosbag2","7",7000000,{"path":3613,"stem":3614,"title":3615,"date":3266,"chapter":3616,"chapterSort":3617,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},"/en-us/wiki/2023-12-30-ros2-tutorial/ch8-zuo-biao-bian-huan-tf","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch8-坐标变换TF","Coordinate Transformation TF","8",8000000,{"path":3619,"stem":3620,"title":3621,"date":3266,"chapter":3622,"chapterSort":3623,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":3273},"/en-us/wiki/2023-12-30-ros2-tutorial/ch9-ke-shi-hua-ping-tai-rviz2-yu-urdf-jian-mo-yu-yan","_i18n/en-us/wiki/2023-12-30-ros2-tutorial/ch9-可视化平台RVIZ2与URDF建模语言","Visualization Platform RVIZ2 and URDF Modeling Language","9",9000000,{"path":3269,"stem":3625,"title":3626,"date":3266,"chapter":3274,"chapterSort":3627,"docKey":3268,"docRoot":3269,"docTitle":3270,"isWikiDoc":87,"isWikiIndex":87},"_i18n/en-us/wiki/2023-12-30-ros2-tutorial/index","ROS2 Robot Operating System Tutorial",0,{"variants":3629},[3630,3631,3634,3637,3640],{"path":3263,"localeSlug":3276,"i18nKey":3272},{"path":3632,"localeSlug":3633,"i18nKey":3272},"/zh-hant/wiki/2023-12-30-ros2-tutorial/ch14-6-7-jian-pan-kong-zhi-jie-dian","zh-hant",{"path":3635,"localeSlug":3636,"i18nKey":3272},"/zh-hk/wiki/2023-12-30-ros2-tutorial/ch14-6-7-jian-pan-kong-zhi-jie-dian","zh-hk",{"path":3638,"localeSlug":3639,"i18nKey":3272},"/zh-tw/wiki/2023-12-30-ros2-tutorial/ch14-6-7-jian-pan-kong-zhi-jie-dian","zh-tw",{"path":3641,"localeSlug":3642,"i18nKey":3272},"/zh-cn/wiki/2023-12-30-ros2-tutorial/ch14-6-7-jian-pan-kong-zhi-jie-dian","zh-cn",[3263,3279,3632,3279,3635,3279,3638,3279,3641,3279],1780671805986]