关于TF变换的学习笔记(二)

7 篇文章 6 订阅
订阅专栏

第二篇学习TF变换的笔记,主要是根据这篇文章学习的.文章写的很好,推荐阅读.

一.TF简介

TF简介:机器人系统通常具有许多随时间变化的坐标系,例如世界坐标系、基座坐标系、夹持器坐标系、头部坐标系等。TF是一个变换系统,它允许在一个坐标系中进行计算,然后在任何所需的时间点将它们转换到另一个坐标系。TF能够回答以下问题:地图坐标系中机器人基座的当前位姿是什么?相对于机器人基座,夹持器中物体的位姿是什么?5秒前,头部坐标系在世界坐标系的什么地方?(注意:这段话里面重要的有两点,一个是不同坐标系的转换,另一个是时间的转换)

TF的优点:分布式系统,即没有单点故障;转换多次时没有数据丢失;没有坐标系之间的中间数据转换的计算成本;用户无需担心其数据的起始坐标系;有关过去位置的信息进行存储并且可访问(在本地记录开始后)。

TF节点:主要是两个一个是发布器,作用是发布坐标系之间的转换关系,主要是tf::Transform 到话题/tf;另一个是订阅器listener,直接订阅/tf并缓存所有的数据到缓存极限.

TF变换树。TF在坐标系之间构建变换树,支持多个非连接树,仅在同一树中变换有效,见下图

不同节点就是不同坐标系之间的变换关系就如上图所示,相邻两个节点间的变换关系只有一条,这个很重要,是保证迭代转换的前提.

有些复杂的工程系统可能有几十个坐标系需要转换,tf可以帮助我们完成这个功能,让我们的主要精力放在算法的设计上.

二.如何使用TF树

假设我们希望robot2根据robot1的激光数据进行导航,给定TF树,

要用到/robot1/laser-------->/robot2/odom:

整个过程用到了Inverse Transform 和Forward Transform两个转换

可以跑一个demo来演示一下,

roslaunch turtle_tf turtle_tf_demo.launch

 我显示了这个:

不知道是什么错误,不是重点,暂时不管.

发现是没有安装包turtle_tf,安装一下就好了:

sudo apt-get install ros-melodic-turtle-tf

 显示控制一个海龟,然后另一个海龟跟随.

分析具体的launch文件的内容

<launch>

 <!-- Turtlesim Node-->
 <node pkg="turtlesim" type="turtlesim_node" name="sim"/>

 <node pkg="turtlesim" type="turtle_teleop_key" name="teleop" output="screen"/>
 <!-- Axes -->
 <param name="scale_linear" value="2" type="double"/>
 <param name="scale_angular" value="2" type="double"/>

 <node name="turtle1_tf_broadcaster" pkg="turtle_tf" type="turtle_tf_broadcaster.py" respawn="false" output="screen" >
   <param name="turtle" type="string" value="turtle1" />
 </node>
 <node name="turtle2_tf_broadcaster" pkg="turtle_tf" type="turtle_tf_broadcaster.py" respawn="false" output="screen" >
   <param name="turtle" type="string" value="turtle2" />
 </node>
 <node name="turtle_pointer" pkg="turtle_tf" type="turtle_tf_listener.py" respawn="false" output="screen" >
 </node>

</launch>

该Demo使用TF库创建3个坐标系,分别是世界坐标系、turtle1坐标系和turtle2坐标系;包含一个TF广播器(broadcaster)发布turtle坐标系,一个TF订阅器(listener)计算两个turtle坐标系之间的距离。

不是重点,略过.

三.TF相关工具

view_frames:可视化完整的坐标变换树;

通过view_frames创建一个由TF使用ROS广播的坐标系变换树

再用下面命令查看

evince frames.pdf

tf_monitor:监视坐标系之间的变换; 

rosrun tf tf_moniter

tf_echo:将指定的变换输出到屏幕;

tf_echo通过ROS广播任意两个坐标系之间的变换,使用示例:

$ rosrun tf tf_echo [reference_frame] [target_frame]

让我们看一下turtle2坐标系相对于turtle1坐标系的变换,它相当于:

就是说turtle1---->turtle2 等价于turtle1--->world--->turtle2

具体命令表示:

rosrun tf tf_echo turtle1 turtle2

roswtf:使用tfwtf插件,帮助我们跟踪TF的问题;

static_transform_publisher:一个用于发送静态变换的命令行工具。

四.广播TF变换

TF广播器将坐标系的相对位姿发送给系统的其余部分,一个系统可以有多个广播器,每个广播器提供机器人不同部分的信息。接下来,我们将编写代码来重现上述tf Demo。

首先新建一个名为lecture1-6的新包,依赖包有tf,roscpp,rospy,turtlesim

然后在src文件下新建一个tf_broadcaster.cpp的文件,内容如下:

#include <ros/ros.h>
#include <tf/transform_broadcaster.h>
#include <turtlesim/Pose.h>

std::string turtle_name;

void poseCallback(const turtlesim::PoseConstPtr& msg){
   static tf::TransformBroadcaster br;
   // 设置一个TF广播器
   tf::Transform transform;
   // 设置T矩阵
   transform.setOrigin(tf::Vector3(msg->x, msg->y, 0.0));
   tf::Quaternion quaternion;
   transform.setRotation(tf::createQuaternionFromYaw(msg->theta));

   br.sendTransform(tf::StampedTransform(transform, ros::Time::now(), "world", turtle_name));
}

int main(int argc, char** argv){
   ros::init(argc, argv, "my_tf_broadcaster");
   if (argc != 2) {
     ROS_ERROR("need turtle name as argument");
     return -1;
  };
   turtle_name = argv[1];

   ros::NodeHandle nh;
   ros::Subscriber sub = nh.subscribe(turtle_name+"/pose", 10, &poseCallback);

   ros::spin();
   return 0;
};

比较简单,相关函数在上一篇笔记有所讲解.

然后在launch中,新建tf_demo.launch文件:

<launch>
    <!-- Turtlesim Node-->
    <node pkg="turtlesim" type="turtlesim_node" name="sim"/>
    <node pkg="turtlesim" type="turtle_teleop_key" name="teleop" output="screen"/>

    <!-- tf broadcaster node -->
    <node pkg="lecture1-6" type="tf_broadcaster"
          args="/turtle1" name="turtle1_tf_broadcaster" />
  </launch>

关键是args里面是我们在运行是需要输入的海龟的名称

运行结果:

 运用前面的命令查询是否成功订阅到turtle的tf

rosrun tf tf_echo /world /turtle1

这个命令是显示/world--->/turtle1的变换

突发奇想,如果颠倒位置会怎么样?

rosrun tf tf_echo /turtle1 /world

应该显示/turtle1--->/world的变换

 正好相反,总是在学新东西的时候有些奇奇怪怪的想法...

之后就是接受模块,在src下创建tf_listener.cpp:

#include <ros/ros.h>
#include <tf/transform_listener.h>
#include <turtlesim/Spawn.h>
#include <geometry_msgs/Twist.h>

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

    ros::NodeHandle node;
    // 参数服务器,生成一只乌龟
    ros::service::waitForService("spawn");
    ros::ServiceClient add_turtle =
       node.serviceClient<turtlesim::Spawn>("spawn");
    turtlesim::Spawn srv;
    add_turtle.call(srv);

    ros::Publisher turtle_vel =
       node.advertise<geometry_msgs::Twist>("turtle2/cmd_vel", 10);

    tf::TransformListener listener;
    ros::Rate rate(10.0);

    while (node.ok()){
        tf::StampedTransform transform;
        try {
            listener.waitForTransform("/turtle2", "/turtle1", ros::Time(0), ros::Duration(10.0) );
            listener.lookupTransform("/turtle2", "/turtle1", ros::Time(0), transform);
        } catch (tf::TransformException &ex) {
            ROS_ERROR("%s",ex.what());
        }

        geometry_msgs::Twist vel_msg;
        vel_msg.angular.z = 4 * atan2(transform.getOrigin().y(),
                                     transform.getOrigin().x());
        vel_msg.linear.x = 0.5 * sqrt(pow(transform.getOrigin().x(), 2) +
                                      pow(transform.getOrigin().y(), 2));

        turtle_vel.publish(vel_msg);

        rate.sleep();
    }
    return 0;
};

核心函数是listener.waitForTransform()和listener.lookupTransform()

之前碰到这两个函数总是搞不清楚,到底是第一个参数到第二个参数的转换,还是反过来,现在在这里把它彻底弄清楚.

关于listener.waitForTransform()

  /** \brief Block until a transform is possible or it times out
   * \param target_frame The frame into which to transform
   * \param source_frame The frame from which to transform
   * \param time The time at which to transform
   * \param timeout How long to block before failing
   * \param polling_sleep_duration How often to retest if failed
   * \param error_msg A pointer to a string which will be filled with why the transform failed, if not NULL
   */
  bool waitForTransform(const std::string& target_frame, const std::string& source_frame,
                        const ros::Time& time, const ros::Duration& timeout, const ros::Duration& polling_sleep_duration = ros::Duration(0.01),
                        std::string* error_msg = NULL) const;

这里的/param target_frame The frame into which to transform的意思就是要转换的目标frame,那这里就是说turtle1--->turtle2

关于listener.lookupTransform()

  /** \brief Get the transform between two frames by frame ID.
   * \param target_frame The frame to which data should be transformed
   * \param source_frame The frame where the data originated
   * \param time The time at which the value of the transform is desired. (0 will get the latest)
   * \param transform The transform reference to fill.  
   *
   * Possible exceptions tf::LookupException, tf::ConnectivityException,
   * tf::MaxDepthException, tf::ExtrapolationException
   */
  void lookupTransform(const std::string& target_frame, const std::string& source_frame,
                       const ros::Time& time, StampedTransform& transform) const;

按源码的解释应该也是turtle1--->turtle2吧.

之后可以测试一下,使用笔记一中的源码,魔改一下.

基本实现了之前的turtle_tf_demo.launch

五.测试想法

测试之前的想法,我的验证想法思路是这样的,先广播设定好的一个坐标系之间的变换关系,然后在用另一个listener.cpp文件中使用这两个函数进行输出.

首先创建一个test_tf功能包,依赖有tf, roscpp, rospy

首先在src中创建test_tf_broadcaster.cpp,内容如下:
 

#include <ros/ros.h>
#include <tf/transform_broadcaster.h>

int main(int argc, char** argv)
{
    ros::init(argc, argv, "publishe_tf");
    ros::NodeHandle nh;
    ros::Rate r(100);

    // 在我的假设中oxis1 ---> oxis2 是(-1, -2, -3)
    //                            oxis2 ---> oxis1 是(1, 2, 3)
    // 所以按我的理解下面的函数发送的就是oxis1 ---> oxis2,其实这里的源码的注释部分已经说的很详细了。
//并且以oxis1为参考坐标系
    tf::TransformBroadcaster br;
    while(nh.ok())
    {
        br.sendTransform(
            tf::StampedTransform(
                tf::Transform(tf::Quaternion(0,0,0,1),tf::Vector3(-1,-2,-3)),
                ros::Time::now(),
                "/oxis1",
                "/oxis2"
            )
        );
        r.sleep();
    }
    return 0;
}

具体的看注释,然后在src下创建test_tf_listener.cpp

#include <ros/ros.h>
#include <tf/transform_listener.h>
#include <geometry_msgs/PointStamped.h>

int main(int argc, char** argv)
{
    ros::init(argc, argv, "listen_tf");
    ros::NodeHandle nh;

    tf::TransformListener listener;
    tf::StampedTransform transform;

    listener.waitForTransform("/oxis1", "/oxis2", ros::Time(0), ros::Duration(10.0) );
    listener.lookupTransform("/oxis1", "/oxis2", ros::Time(0), transform);

    std::cout <<"child_frame_id:" <<std::endl;
    std::cout << transform.child_frame_id_ <<std::endl;

    std::cout <<"frame_id:" <<std::endl;
    std::cout << transform.frame_id_ <<std::endl;

    std::cout <<transform.getOrigin().getX()<<
    transform.getOrigin().getY()<<transform.getOrigin().getZ()<<std::endl;

    return 0;
}

之后的结果发现是与lookupTransform中参数的位置相关,

如果参数一是/oxis1,参数二是/oxis2,那么输出的就是我当时发送的,是从/oxis2---->/oxis1的变换。

如果参数一是/oxis2, 参数而是/oxis1,那么就会自动变换符号。

具体可以自己运行源码分析,不要忘了关于CMakeLists.txt文件的修改。

注意,lookupTransform最好与waitForTransform连用,不然会报错。

tf(Transform Frame)变换
shuijinghua的博客
11-11 1万+
tf是ROS中建立坐标系,并且使用各个坐标间转换关系的一个很好的工具。虽然官网的资料很复杂,但在 一、广播tf     就是发布你建立的坐标系,步骤如下    1. 定义一个广播,相当于发布话题时定义一个发布器。        tf::TransformBroadcaster br;  2. 定义存放转换信息(平动,转动)的变量 transform   tf::Transform ...
ROS学习笔记10:TF坐标变换(ROS常用组件)
qq_71734878的博客
11-22 2941
旋转参数的第一种命令格式使用以弧度为单位的yaw、pitch、roll角度(yaw是围绕z轴旋转的偏航角,pitch是围绕y轴旋转的俯仰角,roll是围绕x轴旋转的翻滚角),第种命令格式使用四元数表达旋转角度。机器人本体和机器人的工作环境中往往存在大量的组件元素,在机器人设计和应用中会涉及不同组件的位置和姿态,这就需要引入坐标系和坐标变换的概念。可视化系统当中的所有tf的关系,监听5s,把5s之内所有坐标系之间的关系保存下来,并生成一个pdf。(2)机器人夹取的物体相对于机器人中心坐标系的位置;
tf Quaternion
WangQiang319670的博客
08-06 4457
class Quaternion : public QuadWord { public: Quaternion() {} Quaternion(const tfScalar&amp; x, const tfScalar&amp; y, const tfScalar&amp; z, const tfScalar&amp; w): QuadWord(x, y, z, w) {} ...
坐标变换-tf::transform
bansongzao8204的博客
07-18 1657
tf::Transform r_to_w(tf::createQuaternionFromYaw(robot_pose_[2]),tf::Vector3(robot_pose_[0],robot_pose_[1],0)); tf::Transform t_to_w(tf::createQuaternionFromYaw(target_pose_[2]),tf::Vector...
tf::transformPose,tf::Transform,tf::Stamped,tf::Pose用法
最新发布
newbeixue的博客
07-10 1629
根据具体的应用场景和需求,可以灵活使用这些方法来操作和管理附带时间戳的姿态和变换数据。该类是TF库中用于存储具有时间戳的姿态和变换的容器,在机器人系统中经常被使用。是TF库中的一个类,用于表示3D空间中的姿态(位置和方向)。它包含了旋转和平移变换的信息,可以用于表示从一个坐标系到另一个坐标系的变换。然后,我们创建了一个新的旋转四元数newRotation和一个新的平移向量newTranslation,并使用。类型的变量centered_laser_pose_,它表示一个时间戳的姿态变换
TensorFlow数据预处理库tf.Transform.zip
07-19
tf.Transform 是一个使用 TensorFlow 进行数据预处理的库。它允许用户结合各种数据处理框架(目前支持 Apache Beam,但是可以扩展 tf.Transform 以支持其他框架),使用 TensorFlow 来转换数据。 因为 tf.Transform 是基于 TensorFlow 构建的,所以它允许用户导出一个计算图(graph),用户随后可以将导出的 TensorFlow 计算图(TensorFlow graph)合并到它们的服务模型中,从而避免服务模型和训练数据之间的偏差。 标签:tfTransform
tf学习笔记1
08-04
TF提供了一种高效、可靠的方法来管理机器人的运动学和传感器数据的坐标变换。以下是对TF相关知识点的详细说明: 1. **TF Tree**: TF树是一种数据结构,用于表示机器人环境中各个坐标系之间的关系。每个节点代表一个...
ROS1学习笔记--tf变换
weixin_40863346的博客
05-29 831
一、tf变换简介         机器人系统通常具有许多随时间变化的3D坐标系,例如世界坐标系(world frame),基准坐标系(base frame),夹具坐标系(gripper frame),头部坐标系(head frame)等。tf包可以随时记录所有这些坐标系,并可以解决如下问题:5秒前,机器人头部坐标系相对于世界(全局)坐标系的关系是什么样的?机器人夹取的物体相对于机器人的中心坐标的位...
tf 矩阵行和列交换_【TF2.1学习笔记4】张量基本操作
weixin_28818559的博客
12-23 292
大纲维度变换改变视图:tf.reshape(x, shape)增、删维度:tf.expand_dims(x, axis)和tf.squeeze(x, axis)变换维度:tf.transpose(x, perm)复制数据:tf.tile(x, multiples)广播四则运算乘方运算指数和对数矩阵运算1. 维度变换1.1 改变视图一个张量有存储和视图两个概念。存储指将张量保存在一个连续的内存区域内...
WUSTC TF Re学习笔记:解密挑战与技术实操
在本次"re学习笔记(56)WUSTCTF-Re方向WP"中,作者分享了他在WUSTC网络安全技术竞赛中的几个挑战经验和解题思路。首先,他提到的是"WUSTCTF-re-Cr0ssFun"任务,通过使用IDA64反汇编器分析,他进入了main函数并观察...
ROS中的tf(transform)的理解 ,你追我小乌龟的深入剖析
凌少skier的小窝
08-16 1万+
对于ros中的tf其实一直理解不是很深,最近工作上一直在用,就很懵逼,出来混果然是要还的~于是这两天把ros官方提供的小乌龟版的你追我,如果你追到我,我就让你xxx,一个一个命令跑了一下,现在有了一个较深的理解,如果哪里说的不对,还请指正。 首先看launch文件内容 <launch> <!-- 海龟仿真器 --> <node pkg="turtle...
C++ tf::TransformListener
YiYeZhiNian的博客
04-30 5332
ROS编写机器人的时候,不免会用到坐标变换,而TF是ROS中建立坐标系,并且使用各个坐标间转换关系的一个很好的工具。 TF库的目的是实现系统中任一个点在所有坐标系之间的坐标变换,也就是说,只要给定一个坐标系下的一个点的坐标,就能获得这个点在其他坐标系下的坐标。 使用TF功能包主要有以下两种方式: A:监听tf变换,接收并缓存系统中发布的所有参考系变换,并从中查询所需要的参考系变换。 B:广播tf变换,向系统中广播参考系之间的坐标变换关系。系统中更可能会存在多个不同部分的tf变换广播,每个广播都可以
TF-POSE video显示节点
Lzw1217的博客
10-02 385
TF-POSE video显示节点 参考资源:https://blog.csdn.net/eereere/article/details/80176007 在 run_video.py 中 原来的42行的 humans = e.inference(image) 改成 humans = e.inference(image, resize_to_default=True, upsample_siz...
ROS中的坐标与坐标系转换
张飞飞的博客
10-04 5681
ROS中的TF 官网建议新工作直接使用tf2,因为它有一个更清洁的界面,和更好的使用体验。(自ROS Hydro以来,tf第一代已被“弃用”,转而支持tf2) TF介绍 TF(TransForm),就是坐标转换,包括了位置和姿态两个方面的变换。注意区分坐标转换和坐标系转换。 坐标转换是一个坐标在不同坐标系下的表示,而坐标系转换不同坐标系的相对位姿关系。 ROS中机器人模型包含大量的部件,每一个部件统称之为link(比如手部、头部、某个关节、某个连杆),每一个link上面对应着一个frame(坐标系), 用f
ROS——一文读懂:tf变换
xiaohu的博客
03-23 5807
https://www.guyuehome.com/355
关于TF转换信息(Transforms)的理解
热门推荐
退休码农飞伯德
05-14 1万+
tf中,我们使用tf工具tf_echo获取到的转换信息十分令人费解。前面的文章中我们已经对其做了简单的解释,这里我们将对其进行详细的解释。
ROS学习笔记6 —— TF的使用
罗伯特祥的博客
07-24 4892
1. tf数据类型 在tf/transform_datatypes.h中定义,基本数据类型有:Quaternion, Vector, Point, Pose, Transform tf::Stamped 对上述数据类型做模板化(除了tf::Transform),并附带元素frame_id_和stamp_ tf::StampedTransform 是tf::Transforms的特例,它要求fr...
ros之tf简介[tf-Package Summary]
mystical的博客
02-22 1468
译者注 第一次翻译技术类文章,难免有许多疏漏,还望见谅。 所使用的ros版本是kinetic 原文地址 以下是译文 tf包的简介 tf是一个允许用户时刻跟踪多个坐标框架的包,它及时地维持树结构中的坐标帧之间的关系,并允许用户在任何时间点变换任何两个坐标帧之间的点、向量等。 变化:自ROS Hydro以来,tf已被“弃用”,转而支持tf2。 tf2是对tf的新版,在更加有效地提供原有功能的基础上...
详解ROS中的TF使用
陈建驱的博客
04-13 5952
个人博客:http://www.chenjianqu.com/ 原文链接:http://www.chenjianqu.com/show-107.html 之前写过一篇博文<ROS-坐标转换>介绍了ROS中坐标转换的概念,并给出实例。在次基础上,本文总结了部分常用的TF的API,以供使用的时候查询。 TF 数据类型 tf::Transform 参考:http://do...
写文章

热门文章

  • ubuntu20.04安装4090驱动 7106
  • CMake多文件编译 5293
  • 解决拯救者r9000p-rtl8852ae无线网卡ubuntu18.04没有网络适配器 3809
  • 20.04安装carla0.9.13记录 3278
  • ros手柄控制机器人小车(一) 3016

分类专栏

  • vtd学习相关 1篇
  • carla 16篇
  • ubuntu 9篇
  • ros相关 7篇
  • docker 1篇
  • slam 28篇
  • 优化库 8篇
  • cmake 1篇
  • pcl相关 2篇
  • 刷题笔记 2篇
  • Carla-rosbridge
  • 数据结构第三版  2篇
  • 洛谷刷题
  • python习题 2篇
  • python
  • slam14讲 1篇
  • 读书笔记 1篇
  • 源码 1篇
  • a tour of c++

最新评论

  • VTD学习笔记(一)-启动vtd、基本界面和按钮

    hex_refugeeeee: 锁mac码了,不能破解

  • VTD学习笔记(一)-启动vtd、基本界面和按钮

    他叫李相赫: 请问VTD是只能用正版的吗?网上好像找不到破解的

  • VTD学习笔记(一)-启动vtd、基本界面和按钮

    hex_refugeeeee: 哈哈哈,好的好的

  • VTD学习笔记(一)-启动vtd、基本界面和按钮

    weixin_64286255: 好巧,我也是今年毕业来公司用的VTD,有空多交流

  • carla学习笔记(十)

    hex_refugeeeee: 我没有试过,但如果官方文档有的话,应该没有问题

大家在看

  • linux—基础命令及相关知识
  • 卷积编码器通过打孔(Puncturing)来修改码率
  • 约束长度、状态数以及清零过程背后的原理

最新文章

  • ubuntu18.04下安装nvidia3090显卡驱动
  • VTD学习笔记(一)-启动vtd、基本界面和按钮
  • carla中lka实现(二)
2024年2篇
2023年32篇
2022年37篇
2021年1篇

目录

目录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值

玻璃钢生产厂家洪山玻璃钢雕塑厂家来宾玻璃钢花盆天津玻璃钢雕塑海鸥山西公园玻璃钢雕塑定制玻璃钢运动鞋雕塑连云港玻璃钢仿铜雕塑多少钱坚实形象卡通游乐园玻璃钢雕塑云浮景观玻璃钢人物雕塑吉安个性化玻璃钢雕塑上海常用商场美陈供应湖南玻璃钢动物雕塑生产厂家甘肃玻璃钢卡通雕塑介绍玻璃钢公仔雕塑代理东坝商场美陈无锡玻璃钢动物雕塑厂家推广凯里玻璃钢雕塑设计公司玻璃钢土豆雕塑卡通人偶江苏商场主题创意商业美陈道具商场店庆美陈布置金山区定制玻璃钢雕塑服务介绍瀍河玻璃钢雕塑价格玻璃钢小黄人雕塑图玻璃钢羊年雕塑镇赉玻璃钢花盆花器福州玻璃钢动物雕塑阜阳抽象玻璃钢雕塑多少钱吉林人物玻璃钢雕塑设计浙江常用商场美陈市场价青岛蔬菜玻璃钢雕塑榆林卡通玻璃钢雕塑制作香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声单亲妈妈陷入热恋 14岁儿子报警汪小菲曝离婚始末遭遇山火的松茸之乡雅江山火三名扑火人员牺牲系谣言何赛飞追着代拍打萧美琴窜访捷克 外交部回应卫健委通报少年有偿捐血浆16次猝死手机成瘾是影响睡眠质量重要因素高校汽车撞人致3死16伤 司机系学生315晚会后胖东来又人满为患了小米汽车超级工厂正式揭幕中国拥有亿元资产的家庭达13.3万户周杰伦一审败诉网易男孩8年未见母亲被告知被遗忘许家印被限制高消费饲养员用铁锨驱打大熊猫被辞退男子被猫抓伤后确诊“猫抓病”特朗普无法缴纳4.54亿美元罚金倪萍分享减重40斤方法联合利华开始重组张家界的山上“长”满了韩国人?张立群任西安交通大学校长杨倩无缘巴黎奥运“重生之我在北大当嫡校长”黑马情侣提车了专访95后高颜值猪保姆考生莫言也上北大硕士复试名单了网友洛杉矶偶遇贾玲专家建议不必谈骨泥色变沉迷短剧的人就像掉进了杀猪盘奥巴马现身唐宁街 黑色着装引猜测七年后宇文玥被薅头发捞上岸事业单位女子向同事水杯投不明物质凯特王妃现身!外出购物视频曝光河南驻马店通报西平中学跳楼事件王树国卸任西安交大校长 师生送别恒大被罚41.75亿到底怎么缴男子被流浪猫绊倒 投喂者赔24万房客欠租失踪 房东直发愁西双版纳热带植物园回应蜉蝣大爆发钱人豪晒法院裁定实锤抄袭外国人感慨凌晨的中国很安全胖东来员工每周单休无小长假白宫:哈马斯三号人物被杀测试车高速逃费 小米:已补缴老人退休金被冒领16年 金额超20万

玻璃钢生产厂家 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化