机器人操作系统:ROS2 仿真入门
塞巴斯蒂安
一、说明
在我的机器人项目中,我从 ROS1 开始,并提供了一个可以使用 RVIZ 可视化的基本机器人模型。然后,我构建了一个实用的原型,完全基于Arduino,不涉及ROS。在项目的当前阶段,我致力于构建一个与视觉传感器兼容的 Gazebo 模型。
本文继续该系列,使用 Gazebo 快速启动 ROS2 模拟。我们将了解创建模拟的基本工具 - ROS启动文件和Gazebo - 并学习应用基本步骤 - 选择3D模型,将它们放置在世界上。
本文的技术背景是 Ubuntu 20.04、ROS2 Foxy、Gazebo11,但它也应该适用于较新的版本。
二、基本机器人仿真术语
本段简要列出了理解物理仿真方面所必需的所有术语。如果您对词汇量很坚定,请跳过本节。
- 运动学:运动学是物理学的一个分支,它控制着身体在时间、位置、速度和加速度方面的运动方式,而不考虑身体的重量或向外力,如重力
- 动力学:物理学的另一个分支,它考虑当物体有质量并受到力影响时物体的位置、速度和加速度如何变化。(在机器人中,这也称为机器人动力学)
- 里程计:一种通过连续记录运动数据来估计物体位置并计算物体移动的距离和轨迹的方法
- 惯性:这种力是运动物体对任何其他会改变其方向、速度或加速度的力的阻力
- 摩擦力:当两个物体靠近另一个物体移动并抵抗该移动时施加的力
- 关节:关节是连接两个物体的机械元件。关节有不同的类型来描述连接的物体如何移动。
来源:ROS机器人编程书
- RPY 值:此首字母缩略词代表横滚、俯仰、偏航,用于描述物体在 3D 空间中的运动。对象可以根据下图在这三个轴上移动:
来源: wikipedia.org
三、循序渐进:如何创建模拟世界
Gazebo是在ROS之外开始的,但后来完全整合了。它更侧重于机器人和世界的完整物理模拟。特别是,世界通过物理引擎提供正确的物理模拟:机器人可以撞到物体,这些物体会移动,最终甚至撞到你的机器人身上。Gazebo 带有预定义的世界模型,您甚至可以定义自己的模型。
在本教程中,我们将启动一个带有空世界的凉亭模拟,然后在里面生成一个机器人。简而言之,基本步骤是:
- 创建新的 ROS 包并设置目录结构
- 创建一个空的坐标定位文件
- 创建启动文件
- 在机器人 URDF 模型中添加其他物理属性
- 参数化机器人 URDF 模型以使用 Gazebo 或 RVIZ 运行。
- 用启动文件开始空的世界
以下各节详细介绍了这些任务。
3.1 第 1 步:包创建和目录结构
我们将创建一个如下所示的包结构:
radu_gazebo/
├── config
│ └── rviz.config
├── launch
│ └── launch.py
├── radu_bot
│ └── __init__.py
├── resource
├── scripts
├── test
├── urdf
│ └── core.xacro
└── worlds
│ └── room.world
├── package.xml
├── setup.cfg
├── setup.py
为方便起见,只需运行以下命令:
ros2 pkg create --build-type python radu_gazebo
mkdir radu_gazebo/launch radu_gazebo/world
mkdir radu_gazebo/launch radu_gazebo/world/room.world
touch radu_gazebo/launch/room.launch
3.2 第 2 步:清空坐标定位文件
该文件是一个SDF文件,将包含我们想要模拟的所有内容的标签:墙壁,窗户和家具等对象。我们将从一个简单的空白世界开始,并逐步添加新对象。room.world
<model>
<!-- FILE: world/room.world -->
<?xml version='1.0'?>
<sdf version="1.6">
<world name="room"><include><uri>model://sun</uri></include><include><uri>model://ground_plane</uri></include>
</world>
</sdf>
您可以手动将此文件加载到凉亭中。但是由于我们最终也将在这个模型中生成一个机器人,因此最好继续直接启动文件。
3.3 步骤 3:启动文件
正如我们在上一篇文章中了解到的,ROS2 不再支持 XML 启动文件,而是使用 Python 文件。
我们使用的启动文件包装包中的启动命令,并提供一个世界参数。gazebo_ros
#!/usr/bin/python3
import os
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument
from launch.actions import IncludeLaunchDescription
from launch.launch_description_sources import PythonLaunchDescriptionSource
package_name = 'radu_bot'
world_file = 'room.world'
def generate_launch_description():pkg_gazebo_ros = get_package_share_directory('gazebo_ros')pkg_radu_simulation = get_package_share_directory(package_name)# launch Gazebo by including its definitiongazebo = IncludeLaunchDescription(PythonLaunchDescriptionSource(os.path.join(pkg_gazebo_ros, 'launch', 'gazebo.launch.py'),))# load the world fileworld_arg = DeclareLaunchArgument('world',default_value=[os.path.join(pkg_radu_simulation, 'worlds', world_file), ''],description='SDF world file')return LaunchDescription([gazebo,world_arg])
3.4 第 4 步:使用 Gazebo 标签扩展机器人模型
为了在凉亭中使用RViz的URDF模型,我们需要对模型进行一些更改。
首先,我们需要为机器人提供额外的物理方面,以便它在模拟中正确运行。其次,机器人的视觉外观不同。RVIZ 模型的颜色和文本定义不适用。如果使用网格,也需要更改它们。第三,我们还需要额外的插件,以便 Gazebo 工具正常工作
让我们逐步查看这些更改。
3.5 物理模拟属性
惯性
物体的惯性是当其当前运动受到另一个物体影响时施加的反作用力。在凉亭模型中,标签用于表示这一方面。<inertial>
下面是一个示例:
<link name="base_link"><inertial><origin xyz="0 0 0" rpy="0 0 0"/><mass value="0.25" /><inertia ixx="0.000486" ixy="0.0" ixz="0.0" iyy="0.000486" iyz="0.0" izz="0.000729"/></inertial><visual><origin rpy="0 0 0" xyz="0 0 0"/><geometry><cylinder radius="0.09" length="0.09"/></geometry></visual>
</link>
标签相对于其父链接定位链接,在这里您可以更改值以移动估计的质量中心。通过您指定此链接质量(以千克为单位)。最后,该元素是 x、y 和 z 上的力如何影响链接的矩阵。您可以在维基百科上阅读物理文章,或使用这个方便的python脚本。<origin>
xyz
<mass>
<inertial>
摩擦
另一组变量控制机器人中链接的摩擦。你用四个值来表达这一点。首先,提供静态和动态接触刚度。在这里,我们使用值和,这是许多ROS项目中使用的默认值。其次,值和是静态和动态摩擦系数,您可以根据链接的材料在维基百科上查找。<kp>
<kd>
100000
1.0
<mu1>
<mu2>
<gazebo reference="base_link"><kp>100000.0</kp><kd>1.0</kd><mu1>10.0</mu1><mu2>10.0</mu2>
</gazebo>
碰撞
这定义了机器人的硬材料边界——它会影响在模拟中将重力和其他力施加到机器人上的方式。这些属性由链接中的标记表示。它的属性非常简单:只需复制原始链接和值,如下所示。<collision>
<geometry>
<origin>
<link name="base_link"><inertial><origin xyz="0 0 0" rpy="0 0 0"/><mass value="0.25" /><inertia ixx="0.000486" ixy="0.0" ixz="0.0" iyy="0.000486" iyz="0.0" izz="0.000729"/></inertial><visual><origin rpy="0 0 0" xyz="0 0 0"/><geometry><cylinder radius="0.09" length="0.09"/></geometry></visual><collision><origin rpy="0 0 0" xyz="0 0 0"/><geometry><cylinder radius="0.09" length="0.09"/></geometry></collision>
</link>
关节特性
机器人中的关节应进一步建模,以表达其真实世界的行为。
- 对于所有非静态、非连续接头,集合和值
<upper>
<lower>
- 对于所有连续接头,添加和限制
<effort>
<velocity>
<joint name="camera_joint"><limit upper="0.5" lower="-0.5"/>
</joint>
<joint name="left_wheel_joint"><limit effort="0.1" velocity="0.005"/>
</joint>
3.6 可视化模拟属性
要更改机器人的视觉效果,您有以下选项:
简单的颜色
这与 RViz 中的工作方式相同:在链接标签中,您可以引用一个元素。<visual>
<color>
<material name="blue"><color rgba="0 0 0.8 1"/>
</material>
<link name="camera"><visuals><material name="blue"></visuals>
</link>
预定义网格
Gazebo 提供了一组内置网格,这些网格在此源代码文件中列出。应用它们,在标签内添加标签,如下所示。<material>
<gazebo>
<gazebo reference="base_link"><material>Gazebo/Grey</material>
</gazebo>
自定义网格
使用自定义网格表示链接时,只需在链接的标记中引用它们,如下所示:<geometry>
<link name="camera"><mesh filename:"package://radu_bot/model/meshes/camera.dae" />
</link>
重要提示:建议不要在标签中使用自定义网格文件,因为这会影响仿真性能。相反,请根据可用的盒子、圆柱体和球体类型定义值。<collision>
<geometry>
3.7 第 5 步:参数化机器人 URDF 模型以使用 Gazebo 或 RViz 跑步
如您所见,所需的更改是根本性的。而且它们不向后兼容:Gazebo 所需的所有更改都无法被 RVIZ 解析。
由于这些原因,复杂的机器人项目将URDF方面分成不同的XACRO文件。经过一些实验,我想出了以下层次结构。
core
- 包含用于渲染机器人链接和关节的核心宏rviz
- RVIZ主文件,它定义参数并导入其他文件rviz_viusals
- 定义机器人在RViz中的可视化方式gazebo
- 凉亭核心文件,就像定义参数和导入其他文件一样gazebo_visuals
- 定义如何在凉亭中可视化机器人gazebo_physics
- 计算链接和标签的附加宏<inertial>
<collision>
gazebo_sensor
- 添加传感器数据gazebo_controll
- 添加了 ROS 控制插件并定义用于渲染标签的宏<transmission>
让我们看看这种方法在实践中是如何工作的。运行 Xacro 渲染模型时,将使用命令 -o radu_rviz_compiled.urdf'。此文件将...xacro rviz.xacro
- 导入其他必需的文件
<xacro:include filename="$(find radu_bot)/urdf2/core.xacro"/>
<xacro:include filename="$(find radu_bot)/urdf2/visuals.xacro"/>
2. 定义控制宏执行的基本参数
<xacro:property name="gazebo_build" value="false" />
<xacro:property name="rviz_build" value="true" />
3. 执行宏以创建 URDF 模型
<xacro:box_link name="base_link" size="0.6 0.3 0.05" color="${torso_color_name}" color_rgb="${torso_color_rgb}" />
<xacro:wheel_link name="right_wheel_frontside" />
<xacro:wheel_joint name="base_link_right_wheel_frontside" parent="base_link" child="right_wheel_frontside" xyz="0.2 -0.2 -0.05" />
<xacro:wheel_link name="right_wheel_backside" />
<xacro:wheel_joint name="base_link_right_wheel_backside" parent="base_link" child="right_wheel_backside" xyz="-0.2 -0.2 -0.05" />
<xacro:wheel_link name="left_wheel_frontside" />
<xacro:wheel_joint name="base_link_left_wheel_frontside" parent="base_link" child="left_wheel_frontside" xyz="0.2 0.2 -0.05" />
<xacro:wheel_link name="left_wheel_backside" />
<xacro:wheel_joint name="base_link_left_wheel_backside" parent="base_link" child="left_wheel_backside" xyz="-0.2 0.2 -0.05" />
在使用这种方法一段时间后,我意识到处理可变性的核心逻辑在文件内部:用于呈现链接和关节的宏具有将由主文件触发的不同块。请参阅以下定义。在第 3 行中,评估条件以添加特定于 RViz 的视觉对象。在第 14 行中,另一个条件检查凉亭物理属性并将其应用于模型。core.xacro
<link>
<xacro:if>
<xacro:macro name="box_link" params="name size color color_rgb" ><link name="${name}"><xacro:if value="${rviz_build}"><visual><origin xyz="0 0 0" rpy="0 0 0"/><geometry><box size="${size}"/></geometry><material name="${color}"><color rgba="${color_rgb}"/></material></visual></xacro:if><xacro:if value="${gazebo_build}"><pose>0 0 0 0 0 0</pose><xacro:box_inertia m="0.6" x="0.7" y="0.4" z="0.2"/><collision name="collision_${name}"><origin xyz="0 0 0" rpy="0 0 0"/><geometry><box size="${size}"/></geometry></collision></xacro:if> </link>
</xacro:macro>
3.8 第 6 步:生成机器人
Gazebo 节点通过启动文件启动,但机器人需要生成到节点中。感谢博客文章如何在 ROS2 中生成机器人,我创建了以下启动文件。
#!/usr/bin/python3
import os
import sys
import rclpy
from gazebo_msgs.srv import SpawnEntity
from ament_index_python.packages import get_package_share_directory
package_name = 'radu_bot'
def main(args=None):rclpy.init(args=args)node = rclpy.create_node('minimal_client')cli = node.create_client(SpawnEntity, '/spawn_entity')sdf_file_path = (os.path.join(get_package_share_directory(package_name), 'urdf', 'radu_gazebo_compiled.urdf')),model = open(sdf_file_path[0], 'r').read()print("MODEL %s" %model)req = SpawnEntity.Request(name = "radu_bot",xml = model,robot_namespace = "radu",reference_frame = "world",)while not cli.wait_for_service(timeout_sec=1.0):node.get_logger().info('service not available, waiting again...')future = cli.call_async(req)rclpy.spin_until_future_complete(node, future)if future.result() is not None:node.get_logger().info('Result ' + str(future.result().success) + " " + future.result().status_message)else:node.get_logger().info('Service call failed %r' % (future.exception(),))node.destroy_node()rclpy.shutdown()
if __name__ == '__main__':main()
启动文件还可以在启动期间转换 Xacro 文件,如diff_bot示例中所示。例如,要加载 Gazebo 配置,您需要执行以下命令:
import xacro
def generate_launch_description():pkg_radu_simulation = get_package_share_directory(package_name)robot_description_path = os.path.join(pkg_radu_simulation,"urdf","gazebo.xacro",)robot_description = {"robot_description": xacro.process_file(robot_description_path).toxml()}
四、启动机器人
首先,我们构建当前工作区。
$> colcon build --symlink-install --cmake-clean-first --event-handlers console_direct+ --packages-up-to radu_bot
然后我们推出凉亭。
$> ros2 launch radu_bot gazebo.launch.py
[INFO] [launch]: All log files can be found below /home/devcon/.ros/log/2021-05-30-09-07-30-541933-giga-36879
[INFO] [launch]: Default logging verbosity is set to INFO
[INFO] [gzserver-1]: process started with pid [36886]
[INFO] [gzclient -2]: process started with pid [36889]
然后生成机器人。
$> ros2 run radu_bot spawn_radu
[INFO] [1622358479.722919377] [minimal_client]: Result True SpawnEntity: Successfully spawned entity [radu_bot]
最后,渲染机器人:
五、结论
本文向您展示了如何从头开始在 ROS2 中创建与 Gazebo 兼容的模拟。事实证明,这是一个漫长的 过程,您需要 (1) 创建一个包,(2) 创建坐标定位文件,(3) 创建启动文件,(4) 将 Gazebo 特定标签添加到我们的机器人模型中,(5) 参数化您的机器人模型以与 Gazebo 和 RVIZ 兼容,以及 (6) 在模拟中生成机器人实体。形成所有这些步骤。添加 Gazebo 物理是学习和应用的时间密集型,我希望您也能获得宝贵的见解。最后,我们可以使用自定义启动脚本文件在 Gazebo 和 RViz 中生成 RADU。从这里,我们可以在模拟中移动机器人。
相关文章:
机器人操作系统:ROS2 仿真入门
塞巴斯蒂安 一、说明 在机器人项目中,仿真是一个具有多种用途的重要方面。首先,您可以测试希望机器人执行的行为代码。其次,您可以使用仿真来测试不同类型的硬件,例如距离传感器、相机或 3D 点云传感器,看看哪种效果最…...
面试题:线程池的底层工作原理
线程池的几个重要的参数: 1、corePoolSize:线程池的核心线程数(也是默认线程数) 2、maximumPoolSize:最大线程数 3、keepAliveTime:允许的线程最大空闲时间(单位/秒) 线程池内部是…...
Excel/PowerPoint条形图改变顺序
条形图是从下往上排的,很多时候不是我们想要的效果 解决方案 选择坐标轴,双击,按下图顺序点击 效果...
【操作系统】虚拟内存相关分段分页页面置换算法
虚拟内存是什么? 【进程地址空间虚拟地址空间C/C程序地址空间就是那个4G的空间】 虚拟内存是操作系统内核为了对进程地址空间进行管理,而设计的一个逻辑意义上的内存空间概念。在程序运行过程中,虚拟内存中需要被访问的部分会被映射到物理内…...
Unrecognized Hadoop major version number: 3.0.0-cdh6.3.2
一.环境描述 spark提交job到yarn报错,业务代码比较简单,通过接口调用获取数据,将数据通过sparksql将数据写入hive中,尝试各种替换hadoop版本,最后拿下 1.hadoop环境 2.项目 pom.xml spark-submit \ --name GridCorr…...
机器学习分类,损失函数中为什么要用Log,机器学习的应用
目录 损失函数中为什么要用Log 为什么对数可以将乘法转化为加法? 机器学习(Machine Learning) 机器学习的分类 监督学习 无监督学习 强化学习 机器学习的应用 应用举例:猫狗分类 1. 现实问题抽象为数学问题 2. 数据准备…...
PySpark安装及WordCount实现(基于Ubuntu)
先盘点一下要安装哪些东西: VMwareubuntu 14.04(64位)Java环境(JDK 1.8)Hadoop 2.7.1Spark 2.4.0(Local模式)Pycharm (一)Ubuntu VMware 和 ubuntu 14.04(…...
SpringBoot 模板模式实现优惠券逻辑
一、计算逻辑的类结构图 在这张图里,顶层接口 RuleTemplate 定义了 calculate 方法,抽象模板类 AbstractRuleTemplate 将通用的模板计算逻辑在 calculate 方法中实现,同时它还定义了一个抽象方法 calculateNewPrice 作为子类的扩展点。各个具…...
并查集 rank 的优化(Java 实例代码)
目录 并查集 rank 的优化 Java 实例代码 UnionFind3.java 文件代码: 并查集 rank 的优化 上一小节介绍了并查集基于 size 的优化,但是某些场景下,也会存在某些问题,如下图所示,操作 union(4,2)。 根据上一小节&…...
TDA4超级玩家浮出水面,行泊一体功能、成本刷到极致
2023年以来,智能驾驶市场进入L2普及、高阶ADAS功能(NOA)大规模量产的新周期,降本增效,打造极致性价比、提升用户体验等,成为了竞争的焦点。 其中,替换更具性价比的硬件平台、传感器复用、系统优…...
3分钟了解Android中稳定性测试
一、什么是Monkey Monkey在英文里的含义是猴子,在测试行业的学名叫“猴子测试”,指的是没有测试经验的人甚至是根本不懂计算机的人(就像一只猴子),不需要知道程序的任何用户交互方面的知识,给他一个程序&a…...
LVS-DR+keepalived实现高可用负载群集
VRRP 通信原理: VRRP就是虚拟路由冗余协议,它的出现就是为了解决静态路由的单点故障。 VRRP是通过一种竞选的一种协议机制,来将路由交给某台VRRP路由。 VRRP用IP多播的方式(多播地址224.0.0.18)来实现高可用的通信&…...
阿里云国际版注册教程
什么是阿里云国际版? 阿里云国际版是阿里云专为海外客户供给的服务器及核算资源,涵盖了云主机、弹性裸金属服务器、容器服务、数据库及安全和监控等一系列云核算解决方案。 与其他云核算服务供给商不同,阿里云国际版在安全性、稳定性、性能方…...
基于百度文心大模型创作的实践与谈论
文心概念 百度文心大模型源于产业、服务于产业,是产业级知识增强大模型。百度通过大模型与国产深度学习框架融合发展,打造了自主创新的AI底座,大幅降低了AI开发和应用的门槛,满足真实场景中的应用需求,真正发挥大模型…...
Java基础知识题(五)
系列文章目录 Java基础知识题(一) Java基础知识题(二) Java基础知识题(三) Java基础知识题(四) Java基础知识题(五) 文章目录 系列文章目录 前言 一 Java的数据连接——JDBC 1. 简述什么是JDBC?重点 2. JDBC PreparedStatement比Statement有什么优势&…...
攻防世界-fileinclude
原题 解题思路 题目已经告诉了,flag在flag.php中,先查看网页源代码(快捷键CTRLU)。 通过抓包修改,可以把lan变量赋值flag。在cookie处修改。新打开的网页没有cookie,直接添加“Cookie: languagephp://filte…...
流媒体服务器SRS的搭建及QT下RTMP推流客户端的编写
一、前言 目前市面上有很多开源的流媒体服务器解决方案,常见的有SRS、EasyDarwin、ZLMediaKit和Monibuca。这几种的对比如下: (本图来源:https://www.ngui.cc/zz/1781086.html?actiononClick) 二、SRS的介绍 SRS&am…...
Effective C++条款11——在operator=中处理“自我赋值”(构造/析构/赋值运算)
“自我赋值”发生在对象被赋值给自己时: class Widget {}; Widget w; // ... w w; // 赋值给自己 这看起来有点愚蠢,但它合法,所以不要认定客户绝不会那么做。此外赋值动作并不总是那么可被一眼辨识出来,例如: a[i] a[j]; …...
可视化绘图技巧100篇基础篇(八)-气泡图(一)
目录 前言 适用场景 图例 绘图工具及代码实现 EXCEL 1、单轴气泡图...
Elasticsearch查询之Disjunction Max Query
前言 Disjunction Max Query 又称最佳 best_fields 匹配策略,用来优化当查询关键词出现在多个字段中,以单个字段的最大评分作为文档的最终评分,从而使得匹配结果更加合理 写入数据 如下的两条例子数据: docId: 1 title: java …...
Lock wait timeout exceeded; try restarting transaction的错误
文章目录 一、异常发现二、异常定位1、锁表语句确认2、实际场景排查三、解决思路1、本次解决方式2、其他场景解决思路扩展1、【治标方法】innodb_lock_wait_timeout 锁定等待时间改大2、【治标方法】事务信息查询3、【治标方法】如果杀掉线程依然不能解决,可以查找执行线程耗时…...
ShardingSphere01-docker环境安装
使用docker安装数据库是一个非常好的选择,后续的读写分离、数据分片等功能的数据库都是由docker创建。 一、安装准备 1、前提条件 Docker可以运行在Windows、Mac、CentOS、Ubuntu等操作系统上 Docker支持以下的CentOS版本: CentOS 7 (64-bit)CentOS …...
Java代码审计13之URLDNS链
文章目录 1、简介urldns链2、hashmap与url类的分析2.1、Hashmap类readObject方法的跟进2.2、URL类hashcode方法的跟进2.3、InetAddress类的getByName方法 3、整个链路的分析3.1、整理上述的思路3.2、一些疑问的测试3.3、hashmap的put方法分析3.4、反射3.5、整个代码 4、补充说明…...
区间预测 | MATLAB实现QRBiGRU双向门控循环单元分位数回归时间序列区间预测
区间预测 | MATLAB实现QRBiGRU双向门控循环单元分位数回归时间序列区间预测 目录 区间预测 | MATLAB实现QRBiGRU双向门控循环单元分位数回归时间序列区间预测效果一览基本介绍模型描述程序设计参考资料 效果一览 基本介绍 MATLAB实现QRBiGRU双向门控循环单元分位数回归时间序列…...
Python面向对象植物大战僵尸
先来一波效果图 来看看如何设计游戏架构 import sysimport pygameclass BaseSprite(pygame.sprite.Sprite):def __init__(self, name):super().__init__()self.image pygame.image.load(name)self.rect self.image.get_rect()class AnimateSprite(BaseSprite):def __init__(…...
大屏模板,增加自适应(包含websocket)
1、简单的Node服务端 const WebSocket require(ws);// 创建 WebSocket 服务器 const wss new WebSocket.Server({ port: 8888 });const getHeader (protocol) > {const protocolArr protocol.split(,)const headers {};for (let i 0; i < protocolArr.length; i …...
电商系统架构设计系列(九):如何规划和设计分库分表?
上篇文章中,我给你留了一个思考题:分库分表该如何设计? 今天这篇文章,我们来聊一下如何规划和设计分库分表,以及要考虑哪些问题。 引言 当要解决海量数据的问题,就必须要用到分布式的存储集群了ÿ…...
从Web 2.0到Web 3.0,互联网有哪些变革?
文章目录 Web 2.0时代:用户参与和社交互动Web 3.0时代:语义化和智能化影响和展望 🎉欢迎来到Java学习路线专栏~从Web 2.0到Web 3.0,互联网有哪些变革? ☆* o(≧▽≦)o *☆嗨~我是IT陈寒🍹✨博客主页&#x…...
QT中资源文件resourcefile的使用,使用API完成页面布局
QT中资源文件resourcefile的使用 之前添加图标的方法使用资源文件的方法创建资源文件资源文件添加前缀资源文件添加资源使用资源文件中的资源 使用API完成布局使用QHBoxLayout完成水平布局使用QVBoxLayout完成垂直布局使用QGridLayout完成网格布局 在Qt中引入资源文件好处在于他…...
2337. 移动片段得到字符串
题目描述: 给你两个字符串 start 和 target ,长度均为 n 。每个字符串 仅 由字符 ‘L’、‘R’ 和 ‘_’ 组成,其中: 字符 ‘L’ 和 ‘R’ 表示片段,其中片段 ‘L’ 只有在其左侧直接存在一个 空位 时才能向 左 移动&a…...
wordpress freeradius/网店代运营骗局
多租户SaaS平台的数据库方案 1.1 多租户是什么 多租户技术(Multi-TenancyTechnology)又称多重租赁技术:是一种软件架构技术,是实现如何在多用户环境下 (此处的多用户一般是面向企业用户)共用相同的系统或…...
网站 申请/知乎推广合作
今天我们来聊点接地气的话题,比如关心一下粮食和蔬菜。这就不得不提到中国人最不容置喙的种族天赋,那就是种地!种地,让我们充满了想象力。有条件要种,没有条件创造条件也要种:种地,让我们团结一…...
网站建设委托协议/360信息流广告平台
之前一直用的开源社区的版本,最近突然想到找一个好的商业版本用着,然后一直使用,然后就定上了hdp和cdh,都装上去了,但是cdh使用难度太大了,和开源版本的差距比较大,api不会使用,需要…...
wordpress 后台管理模板/比较正规的代运营
来源:网络整理根据企查查消息显示,华为电动技术有限公司已经成立,注册资本 2.5 亿人民币,法定代表人为王军,由华为技术有限公司100%持股。其经营范围包括工程和技术研究和试验发展;智能车载设备销售&#x…...
做网站论文/企业培训十大热门课程
网格搜索算法和K折交叉验证法是机器学习入门的时候遇到的重要的概念。 网格搜索算法是一种通过遍历给定的参数组合来优化模型表现的方法。 以决策树为例,当我们确定了要使用决策树算法的时候,为了能够更好地拟合和预测,我们需要调整它的参数…...
一起作做业网站/天天seo伪原创工具
bitsCN.comLinux下均在控制台下操作。导入数据库:前提:数据库和数据表要存在(已经被创建)(1)将数据表 test_user.sql 导入到test 数据库的test_user 表中[roottest ~]# mysql -uroot -p test < /www/web/test/test_user.sql(2) 将数据库 test.sql 导入…...