機(jī)器人操作系統(tǒng)ROS:從入門到放棄(三) 發(fā)布接收不同消息2

上一講我們講了如何發(fā)布接收int粗截,float和array類型的消息惋耙,這些也都算是c++自有的消息,被歸納在ROS中的std_msgs這個(gè)命名空間下(命名空間skr啥熊昌?).這講我們來看看如何發(fā)布接收ROS自己獨(dú)特的message類型:PoseStamped.Pose好理解绽榛,就是機(jī)器人的位姿(position and orientation),那么Stamped呢浴捆?Stamped表示時(shí)間戳(timestamped)蒜田,這兒時(shí)間戳是指時(shí)間戳是指格林威治時(shí)間1970年01月01日00時(shí)00分00秒起至現(xiàn)在的總納秒.幾乎所有的計(jì)算機(jī)都可以使用這個(gè)時(shí)間,方便統(tǒng)一.所以PoseStamped記錄的是機(jī)器人的位姿加上記錄位姿的時(shí)間這么一種message.這個(gè)message被包含在geometry_msgs這個(gè)大類下.所以你可以先搜ROS, geometry message查看.第一個(gè)網(wǎng)頁應(yīng)該就是下面這個(gè)
http://wiki.ros.org/geometry_msgs
里面又有一大堆不同類型的消息选泻,你以后都可能用到.但這兒我們就用PoseStamped舉例了冲粤,位姿加時(shí)間還是比較有代表性.
找到頁面中的PoseStamped并點(diǎn)擊進(jìn)入美莫,會發(fā)現(xiàn)下面的內(nèi)容

poseStampedDef.png

你如果想使用這個(gè)消息,那么看到這個(gè)頁面梯捕,根據(jù)我們之前講的內(nèi)容厢呵,你至少可以做下面這幾件事
1: 包含頭文件#include "geometry_msgs/PoseStamped.h",這樣我們才可以使用這個(gè)類型的消息
2:  通過geometry_msgs::PoseStamped msg定義一個(gè)叫msg的對象傀顾,該對象可以使用上圖中的header,pose兩個(gè)數(shù)據(jù)成員.即你可以通過msg.header,msg.pose來調(diào)用數(shù)據(jù)類型為std_msgs/Header,geometry_msgs/Pose的兩個(gè)數(shù)據(jù)成員.

但是那個(gè)header和pose具體是什么東西我們不清楚.但之前說了襟铭,任何復(fù)雜數(shù)據(jù)類型都是由簡單的組成的,頁面下的淺藍(lán)色字體是鏈接可以點(diǎn)進(jìn)去短曾,咱們先點(diǎn)擊std_msgs/Header看看他是個(gè)什么東西.你會看到下圖內(nèi)容.

headerDef.png

uint32和string就是基礎(chǔ)變量了.通過Compact Message Definition可以知道寒砖,如果我們通過std_msgs::Header msg_header創(chuàng)建了一個(gè)叫msg_header類型的對象的話,那么它可以通過msg_header.seq調(diào)用類型為unit32的成員seq.也就是說嫉拐,代碼里你可以用類似于

int a = 1 , b;
msgs_header.seq = 1; 
//or
b = msg_header.seq;

這種代碼給msgs_header.seq賦值或者把它賦值給其他整型變量.可能你要問了哩都,seq定義的不是uint32么,我對a,b的定義就是int婉徘,會不會出問題漠嵌?有可能.這時(shí)候又要用到下面這個(gè)網(wǎng)站了
http://wiki.ros.org/msg
找到uint32對應(yīng)的c++定義是什么,發(fā)現(xiàn)是uint32_t盖呼,所以你直接用儒鹿,uint32_t 定義 a,b是最好的.int是整型,uint32_t是無符號32位整型几晤,兩者的范圍不一樣约炎,這個(gè)可以自己上網(wǎng)查,但是a,b在他們交集的范圍內(nèi)就不會改變具體的數(shù)值.總之同理你可以給msg_header.frame_id賦值string類型的變量.
但這個(gè)time是個(gè)什么東西呢锌仅?標(biāo)準(zhǔn)數(shù)據(jù)類型可沒有這個(gè)玩意兒.不過上面的Raw Message Definition給出解釋了章钾,stamp.sec返回從epoch開始的秒為單位的時(shí)間,stamp.nsec返回從stamp_sec開始的納秒時(shí)間.
msgs_heder.stamp調(diào)用stamp热芹,stamp.sec調(diào)用sec得到epoch的時(shí)間贱傀,那么msgs_header.stamp.sec就可以獲取當(dāng)前的時(shí)間,秒為單位
通常我們肯定需要更精確的時(shí)間即包含納秒的伊脓,假設(shè)我們想把當(dāng)前的精確時(shí)間賦值給變量store_time府寒,那么代碼類似于下面這樣.

double store_time;
store_time = msg_header.stamp.sec + 1e-9*msg_header.stamp.nsec; //unit s
//or
store_time = msgs_header.stamp.sec * 1e9 + msg_header.stamp.nsec; //unit ns

nsec的單位是納秒,我們要乘以1e-9才能轉(zhuǎn)換為秒报腔,第二行得到的是時(shí)間以秒為單位.第四行得到的時(shí)間是以ns為單位.

好了株搔,header說了這么多,目前我們想要這兒的stamp記錄一個(gè)時(shí)間.最開始我們定義了geometry_msgs::PoseStamped msg
msg包含數(shù)據(jù)成員header纯蛾,而heaer作為std_msgs/Header的數(shù)據(jù)成員包含stamp纤房,那么我們可以通過msg.header.stamp調(diào)用數(shù)據(jù)類型為time的成員stamp,為什么能這么做翻诉,我們下一張會講到.ROS可以很方便獲取當(dāng)前時(shí)間ros::Time::now()炮姨,返回的是time類型的變量.所以我們可以通過

msg.header.stamp = ros::Time::now()

來獲取當(dāng)前時(shí)間并儲存在這個(gè)message中.在賦值之后捌刮,如果想要取出我記錄那個(gè)位姿時(shí)的時(shí)間并且是double類型呢?根據(jù)上面的內(nèi)容舒岸,很容易可以得到.

double store_time;
store_time = msg.header.stamp.sec + 1e-9*msg.header.stamp.nsec; //unit s 
//or
store_time =  msg.header.stamp.sec * 1e9 +  msg.header.stamp.nsec; //unit ns

注意不要以為msg.header 等于msg_header哈...只是上面的例子我恰巧給std_msgs::Header對象取名叫msg_header罷了.張三李四都可以.msg.headergeometry_msgs::PoseStamped的對象msg調(diào)用數(shù)據(jù)成員header绅作,而msg_headerstd_msgs::Header的對象.
說完header,我們可以看msg的另一個(gè)數(shù)據(jù)成員pose了.同樣蛾派,我們點(diǎn)擊第一張圖片中的淺藍(lán)色字體geometry_msgs/Pose看一看它具體是由什么基本變量構(gòu)成的.點(diǎn)擊進(jìn)去之后我們進(jìn)入了Pose的定義的界面.Pose的數(shù)據(jù)成員是positionorientation俄认,非常好理解,位置和方向.他們倆的數(shù)據(jù)類型分別是geometry_msgs/Pointgeometry_msgs/Quaternion.這倆也不是基本數(shù)據(jù)類型洪乍,你可以繼續(xù)點(diǎn)進(jìn)去直到變量只有基本數(shù)據(jù)類型.這兒為了簡潔眯杏,我直接畫了個(gè)圖,把PoseStamped包含的成員一一列了出來.

geometry_msgs.png

看這個(gè)圖就一目了然了.(免費(fèi)用了人家的東西得打個(gè)廣告典尾,這個(gè)圖是用一個(gè)叫ProcessOn的在線軟件畫出來的役拴,該軟件用來畫流程圖糊探,思維圖钾埂,結(jié)構(gòu)圖什么的非常方便).
Header部分已經(jīng)講過.咱們繼續(xù)看geometry/msgs/Pose類型的數(shù)據(jù)pose所包含的成員
1是geometry_msgs/Point類型的position,而position包含三個(gè)float64的變量x,y,z科平,這個(gè)很好理解了褥紫,怎么定義機(jī)器人的位置?三維坐標(biāo)x,y,z就可以了.
2是geometry_msgs/Quaternion類型的'oreintation'瞪慧,而oreintation包含四個(gè)float64的變量x,y,z,w髓考,quaterion中文四元數(shù),是一個(gè)用來表示方向的東西.四元數(shù)的缺點(diǎn)是不很形象弃酌,不熟的人很難直接通過四元數(shù)在腦海里構(gòu)想出機(jī)器人目前到底是個(gè)什么朝向.我們一般用歐拉角表示方向時(shí)氨菇,一共有三個(gè)數(shù)roll,pitch,yaw,比較直觀妓湘,但是歐拉角表示方向時(shí)會遇到一個(gè)叫Gimbal Lock(萬向鎖)的尷尬問題查蓉,所以ROS里統(tǒng)一用四元數(shù)表示方向.ROS當(dāng)然提供了一些API把四元數(shù)轉(zhuǎn)換成歐拉角或者旋轉(zhuǎn)矩陣之類的,但是在儲存pose的時(shí)候榜贴,都統(tǒng)一用四元數(shù)儲存.如果不清楚四元數(shù)的同學(xué)可以網(wǎng)上查一下豌研,很多資料.
數(shù)據(jù)的結(jié)構(gòu)說完了,怎么使用呢唬党?和msg.header.stamp.sec調(diào)用int32類型的成員sec一樣鹃共,咱們可以用msg.pose.position.x調(diào)用或者賦值float64的成員x.直接用代碼來說明.接下來我們要建立一個(gè)叫pub_poseStamped.cpp的文件和sub_poseStamped.cpp的文件.第一個(gè)文件咱們來人工產(chǎn)生一些pose,恩驶拱,霜浴,,我相信很多同學(xué)手上沒有直接可以和ROS溝通的傳感器用的.產(chǎn)生了這些pose后我們把他們發(fā)布出去用接收器接收.
和之前一樣蓝纲,我們先在pub_sub_test/src中創(chuàng)建一個(gè)名字叫pub_poseStamped.cpp的文件.在文件中寫入下面的內(nèi)容.

#include "ros/ros.h"
#include "geometry_msgs/PoseStamped.h" //include posestamp head file

#include <cmath>//for sqrt() function

int main(int argc, char **argv)
{
    ros::init(argc, argv, "talker");

    ros::NodeHandle n;

    ros::Publisher chatter_pub = n.advertise<geometry_msgs::PoseStamped>("chatter", 10); //initialize chatter

    ros::Rate loop_rate(10);

    //generate pose by ourselves.
    double positionX, positionY, positionZ;
    double orientationX, orientationY, orientationZ, orientationW;

    //We just make the robot has fixed orientation. Normally quaternion needs to be normalized, which means x^2 + y^2 + z^2 +w^2 = 1
    double fixedOrientation = 0.1;
    orientationX = fixedOrientation ;
    orientationY = fixedOrientation ;
    orientationZ = fixedOrientation ;
    orientationW = sqrt(1.0 - 3.0*fixedOrientation*fixedOrientation); 

    double count = 0.0;
    while (ros::ok())
    {
        //We just make the position x,y,z all the same. The X,Y,Z increase linearly
        positionX = count;
        positionY = count;
        positionZ = count;

        geometry_msgs::PoseStamped msg; 

        //assign value to poseStamped

            //First assign value to "header".
        ros::Time currentTime = ros::Time::now();
        msg.header.stamp = currentTime;

            //Then assign value to "pose", which has member position and orientation
        msg.pose.position.x = positionX;
        msg.pose.position.y = positionY;
        msg.pose.position.z = positionY;

        msg.pose.orientation.x = orientationX;
        msg.pose.orientation.y = orientationY;
        msg.pose.orientation.z = orientationZ;
        msg.pose.orientation.w = orientationW;

        ROS_INFO("we publish the robot's position and orientaion"); 
        ROS_INFO("the position(x,y,z) is %f , %f, %f", msg.pose.position.x, msg.pose.position.y, msg.pose.position.z);
        ROS_INFO("the orientation(x,y,z,w) is %f , %f, %f, %f", msg.pose.orientation.x, msg.pose.orientation.y, msg.pose.orientation.z, msg.pose.orientation.w);
        ROS_INFO("the time we get the pose is %f",  msg.header.stamp.sec + 1e-9*msg.header.stamp.nsec);

        std::cout<<"\n \n"<<std::endl; //add two more blank row so that we can see the message more clearly

        chatter_pub.publish(msg);

        ros::spinOnce();

        loop_rate.sleep();

        ++count;
    }


  return 0;
}

咱們在發(fā)布器的代碼中fixedOrientation的變量阴孟,賦值0.1房铭,然后分別賦值給創(chuàng)建的double類型變量orientationX,Y,Z,W.在循環(huán)中,orientationX,Y,Z,W在分別賦值給我們創(chuàng)建的msg的成員變量msg.pose.orientation.x y z w.為什么能這么賦值温眉?通過上面數(shù)據(jù)結(jié)構(gòu)那張圖我們了解到的msg.pose.orientation.x y z w都是float64類型的變量缸匪,賦值了他們幾個(gè)就可以定義pose的orientation了.orientation是相同的數(shù),那么機(jī)器人就沒有旋轉(zhuǎn).
那么pose的position的x y z我們直接賦值了count类溢,count在循環(huán)中遞增凌蔬,那么XYZ都同時(shí)遞增且相同.如果我們畫一個(gè)三維坐標(biāo)軸XYZ的話,那么咱么這兒模擬的機(jī)器人的運(yùn)動(dòng)狀態(tài)闯冷,相當(dāng)于機(jī)器人沿著坐標(biāo)軸對角線勻速直線行駛.
同樣位置再創(chuàng)建一個(gè)sub_poseStamped.cpp.寫入下面內(nèi)容.

#include "ros/ros.h"
#include "geometry_msgs/PoseStamped.h" 

void chatterCallback(const geometry_msgs::PoseStamped::ConstPtr& msg) //Note it is geometry_msgs::PoseStamped, not std_msgs::PoseStamped
{
    ROS_INFO("I heard the pose from the robot"); 
    ROS_INFO("the position(x,y,z) is %f , %f, %f", msg->pose.position.x, msg->pose.position.y, msg->pose.position.z);
    ROS_INFO("the orientation(x,y,z,w) is %f , %f, %f, %f", msg->pose.orientation.x, msg->pose.orientation.y, msg->pose.orientation.z, msg->pose.orientation.w);
    ROS_INFO("the time we get the pose is %f",  msg->header.stamp.sec + 1e-9*msg->header.stamp.nsec);

    std::cout<<"\n \n"<<std::endl; //add two more blank row so that we can see the message more clearly
}

int main(int argc, char **argv)
{
    ros::init(argc, argv, "listener");

    ros::NodeHandle n;

    ros::Subscriber sub = n.subscribe("chatter", 10, chatterCallback);

    ros::spin();

    return 0;
}

寫完之后砂心,我們同樣打開位于pub_sub_test目錄下的CMakeLists.txt添加編譯兩個(gè)文件的內(nèi)容.保存退出后使用catkin_make編譯(注意catkin_make這個(gè)命令要在catkin_ws這個(gè)目錄下使用的).

結(jié)果編譯出錯(cuò)了!蛇耀!錯(cuò)誤大概長下面的樣子


error_poseStamped.png

讀不懂啥意思氨绲.仔細(xì)對比看看前面的內(nèi)容和你之前編譯pub_int8, pub_string等文件時(shí)有沒有什么出入?經(jīng)過仔細(xì)的檢查纺涤,發(fā)現(xiàn) 木有.所有步驟都是一毛一樣的.那么問題出在哪兒呢译暂?
記得我們當(dāng)初創(chuàng)建pub_sub_test這個(gè)package的時(shí)候,我們是這么創(chuàng)建的

catkin_create_pkg pub_sub_test  std_msgs  roscpp rospy

我們說三個(gè)依賴項(xiàng)std_msgs roscpp rospy就好像C++的頭文件一樣撩炊,如果我們要使用ROS自帶的std_msgs這個(gè)包外永,我們就需要添加這個(gè)依賴項(xiàng).那么現(xiàn)在問題很明顯了,我們?nèi)鄙偬砑?code>geometry_msgs這個(gè)依賴項(xiàng).可以想象拧咳,如果當(dāng)初我們創(chuàng)建package時(shí)用的下面的內(nèi)容伯顶,就不會有什么問題了

catkin_create_pkg pub_sub_test  std_msgs geometry_msgs  roscpp rospy

可是我們package已經(jīng)創(chuàng)建了,又不能重新創(chuàng)建一個(gè)相同名字的package把依賴項(xiàng)加進(jìn)去.那該怎么辦呢骆膝?
當(dāng)我們需要添加新的依賴項(xiàng)時(shí)祭衩,我們需要修改兩個(gè)文件,一個(gè)是package目錄下的CMakeLists.txt阅签,另一個(gè)是位于同一位置的package.xml
打開CMakeLists.txt掐暮,發(fā)現(xiàn)就在最前面幾行,有下面的內(nèi)容.

find_package(catkin REQUIRED COMPONENTS
  roscpp
  rospy
  std_msgs
)

括號中的內(nèi)容正好一一對應(yīng)我們創(chuàng)建package時(shí)添加的依賴項(xiàng)愉择,那么想都不用想啦劫乱,肯定要在后面添加geometry_msgs,變成下面的樣子锥涕,保存退出.

find_package(catkin REQUIRED COMPONENTS
  roscpp
  rospy
  std_msgs
  geometry_msgs
)

添加完成后衷戈,保存退出.之后打開位于同一目錄下的package.xml.(直接雙擊打開可能不能修改其中內(nèi)容,還是用gedit什么的打開).打開之后层坠,在文檔下方殖妇,你可以看到一下內(nèi)容

  <build_depend>roscpp</build_depend>
  <build_depend>rospy</build_depend>
  <build_depend>std_msgs</build_depend>
  <build_export_depend>roscpp</build_export_depend>
  <build_export_depend>rospy</build_export_depend>
  <build_export_depend>std_msgs</build_export_depend>
  <exec_depend>roscpp</exec_depend>
  <exec_depend>rospy</exec_depend>
  <exec_depend>std_msgs</exec_depend>

啊哈,又有std_msgs, rospy, roscpp破花,只不過每個(gè)出現(xiàn)了三次谦趣,那么同樣疲吸,不用管什么意思,我們只需要按照這個(gè)文檔里相同的語法讓geometry_msgs出現(xiàn)三次就行了.更改之后該文件同樣位置變成下面的內(nèi)容

  <build_depend>roscpp</build_depend>
  <build_depend>rospy</build_depend>
  <build_depend>std_msgs</build_depend>
  <build_depend>geometry_msgs</build_depend>
  <build_export_depend>roscpp</build_export_depend>
  <build_export_depend>rospy</build_export_depend>
  <build_export_depend>std_msgs</build_export_depend>
  <build_export_depend>geometry_msgs</build_export_depend>
  <exec_depend>roscpp</exec_depend>
  <exec_depend>rospy</exec_depend>
  <exec_depend>std_msgs</exec_depend>
  <exec_depend>geometry_msgs</exec_depend>

保存退出.這時(shí)候再用catkin_make編譯前鹅,就成功了.改變上面兩個(gè)文檔的內(nèi)容就相當(dāng)于我們在創(chuàng)建package時(shí)添加了依賴項(xiàng)geometry_msgs.編譯成功之后摘悴,跑程序的方法和以前的例子一樣.

總結(jié)

這一講我們講述了一個(gè)稍微復(fù)雜一點(diǎn)的message類型:poseStamped.我們需要通過ROS wiki的幫助知道它包含什么數(shù)據(jù)成員,了解它包含的數(shù)據(jù)成員之后舰绘,利用類對象引用數(shù)據(jù)成員的方法(就像msg.pose.orientation)的方法蹂喻,就可以調(diào)用或者賦值相應(yīng)類型的成員了.因?yàn)槲覀兪稚蠜]有傳感器,我們自己產(chǎn)生了double類型的變量賦值捂寿,從最底層float64 x y z之類的開始賦值口四,模擬機(jī)器人的運(yùn)動(dòng).但其實(shí)如果一個(gè)好的定位傳感器自己有ROS的接口的話,很可能直接產(chǎn)生geometry_msgs/Point類型的變量秦陋,假設(shè)名字叫currentPosition蔓彩,那么我們通過msg.pose.position = currentPosition給pose的位置賦值就可以了,因?yàn)?code>pose.position也是geometry_msgs/Point類型的變量.這個(gè)大家接觸具體的傳感器就知道了.

另外這一講講了如何添加新的ROS依賴項(xiàng).

那么目前我們總共聊了怎么發(fā)布string,int8,array和poseStamped.關(guān)于不同類型的消息驳概,我們就講到這兒了.希望大家以后面對自己想要發(fā)布的不同類型的消息的時(shí)候赤嚼,知道在ROS wiki中怎么找到并看懂相應(yīng)的資料.

下下講我們會介紹如何在類中發(fā)布和接收消息.在這之前呢,為了照顧到語言不那么熟的同學(xué)抡句,我們可能下講就先回顧一下C++類的內(nèi)容.還會提到命名空間和模版探膊,并且和ROS中出現(xiàn)的語法對應(yīng)起來.語言熟悉的同學(xué)就可以跳過下一講了.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市待榔,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌流济,老刑警劉巖锐锣,帶你破解...
    沈念sama閱讀 221,273評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異绳瘟,居然都是意外死亡雕憔,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評論 3 398
  • 文/潘曉璐 我一進(jìn)店門糖声,熙熙樓的掌柜王于貴愁眉苦臉地迎上來斤彼,“玉大人,你說我怎么就攤上這事蘸泻×鹞” “怎么了?”我有些...
    開封第一講書人閱讀 167,709評論 0 360
  • 文/不壞的土叔 我叫張陵悦施,是天一觀的道長并扇。 經(jīng)常有香客問我,道長抡诞,這世上最難降的妖魔是什么穷蛹? 我笑而不...
    開封第一講書人閱讀 59,520評論 1 296
  • 正文 為了忘掉前任土陪,我火速辦了婚禮,結(jié)果婚禮上肴熏,老公的妹妹穿的比我還像新娘鬼雀。我一直安慰自己,他們只是感情好蛙吏,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,515評論 6 397
  • 文/花漫 我一把揭開白布取刃。 她就那樣靜靜地躺著,像睡著了一般出刷。 火紅的嫁衣襯著肌膚如雪璧疗。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,158評論 1 308
  • 那天馁龟,我揣著相機(jī)與錄音崩侠,去河邊找鬼。 笑死坷檩,一個(gè)胖子當(dāng)著我的面吹牛却音,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播矢炼,決...
    沈念sama閱讀 40,755評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼系瓢,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了句灌?” 一聲冷哼從身側(cè)響起夷陋,我...
    開封第一講書人閱讀 39,660評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎胰锌,沒想到半個(gè)月后骗绕,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,203評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡资昧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,287評論 3 340
  • 正文 我和宋清朗相戀三年酬土,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片格带。...
    茶點(diǎn)故事閱讀 40,427評論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡撤缴,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出叽唱,到底是詐尸還是另有隱情屈呕,我是刑警寧澤,帶...
    沈念sama閱讀 36,122評論 5 349
  • 正文 年R本政府宣布尔觉,位于F島的核電站凉袱,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜专甩,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,801評論 3 333
  • 文/蒙蒙 一钟鸵、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧涤躲,春花似錦棺耍、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,272評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至嫩挤,卻和暖如春害幅,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背岂昭。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評論 1 272
  • 我被黑心中介騙來泰國打工以现, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人约啊。 一個(gè)月前我還...
    沈念sama閱讀 48,808評論 3 376
  • 正文 我出身青樓邑遏,卻偏偏與公主長得像,于是被迫代替她去往敵國和親恰矩。 傳聞我的和親對象是個(gè)殘疾皇子记盒,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,440評論 2 359

推薦閱讀更多精彩內(nèi)容