0%

简介

  • python3 bs4模块相关笔记

python3 bs4模块 详解

BeautifulSoup 是一个用于从HTML和XML文档中提取数据的Python库。它为用户提供了简单的API,使得解析、导航和搜索文档树变得更加直观和高效。以下是BeautifulSoup库的一些关键概念和使用方法的详细介绍。

1. 安装

首先,你需要安装 BeautifulSoup4 以及一个解析器库(例如 lxmlhtml.parser)。

1
pip install beautifulsoup4 lxml

2. 基本使用

导入模块并创建 BeautifulSoup 对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from bs4 import BeautifulSoup

html_doc = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title"><b>The Dormouse's story</b></p>
<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
</body>
</html>
"""

soup = BeautifulSoup(html_doc, 'lxml') # 使用 lxml 解析器

3. 基本导航

BeautifulSoup 提供了多种方式来导航和操作文档树。

3.1 标签选择

你可以使用标签名直接选择标签。

1
2
3
print(soup.title)  # <title>The Dormouse's story</title>
print(soup.title.name) # title
print(soup.title.string) # The Dormouse's story

3.2 获取标签的属性

标签的属性可以当作字典来访问。

1
2
3
print(soup.a)  # <a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>
print(soup.a['href']) # http://example.com/elsie
print(soup.a['class']) # ['sister']

3.3 直接子节点和所有子节点

contents 属性可以返回直接子节点列表,children 可以用于遍历直接子节点,而 descendants 则会递归遍历所有子节点。

1
2
3
4
5
6
print(soup.body.contents)  # 直接子节点
for child in soup.body.children:
print(child)

for descendant in soup.body.descendants:
print(descendant)

4. 搜索文档树

BeautifulSoup 提供了几种查找文档树中特定元素的方法。

4.1 find_all()

查找所有符合条件的元素。

1
2
3
links = soup.find_all('a')
for link in links:
print(link['href'])

4.2 find()

查找第一个符合条件的元素。

1
2
first_link = soup.find('a')
print(first_link['href']) # http://example.com/elsie

4.3 使用 CSS 选择器

你可以使用 .select() 方法通过CSS选择器语法查找元素。

1
print(soup.select('p.title'))  # 选择类名为 title 的 <p> 标签

5. 修改文档树

BeautifulSoup 允许你直接修改文档内容。

5.1 修改标签内容

你可以直接修改标签的 .string 属性来更改其内容。

1
2
soup.title.string = "New Title"
print(soup.title) # <title>New Title</title>

5.2 插入和删除标签

你可以使用 append()insert()decompose() 等方法来添加或删除标签。

1
2
3
4
5
new_tag = soup.new_tag("p")
new_tag.string = "This is a new paragraph."
soup.body.append(new_tag) # 添加新标签到 body

soup.p.decompose() # 删除第一个 <p> 标签

6. 输出修饰后的HTML

修改完文档树后,你可以使用 prettify() 方法以缩进格式输出HTML。

1
print(soup.prettify())

7. 使用示例

一个简单的例子,展示如何提取所有链接,并打印它们的文本和链接地址:

1
2
for link in soup.find_all('a'):
print(f"Text: {link.string}, URL: {link['href']}")

8. 处理复杂的HTML

BeautifulSoup 可以非常有效地处理和解析有错误或不完整的HTML。它会自动修复文档树,使其更易于解析。


这就是 BeautifulSoup 库的基本使用方法和主要功能。通过这些方法,你可以轻松地从复杂的HTML文档中提取所需的信息。

简介

  • pandas模块相关笔记

python3 pandas模块 详解

Pandas 是 Python 数据分析中最常用的库之一,它提供了数据结构和数据分析工具,尤其擅长处理表格数据。以下是 Pandas 模块的一些详细介绍。

1. 安装 Pandas

在使用 Pandas 之前,你需要确保已经安装了它。可以使用以下命令进行安装:

1
pip install pandas

2. 导入 Pandas

导入 Pandas 通常使用 pd 作为别名:

1
import pandas as pd

3. 核心数据结构

3.1 Series

Series 是 Pandas 的基本数据结构之一,它是一维的,类似于 Python 中的列表或字典。

1
2
3
4
5
import pandas as pd

# 创建一个简单的 Series
s = pd.Series([1, 3, 5, 7, 9])
print(s)

3.2 DataFrame

DataFrame 是 Pandas 中最重要的数据结构,它是一个二维的表格数据结构,可以理解为一个“表格”或“电子表格”。

1
2
3
4
5
6
7
8
9
# 创建一个简单的 DataFrame
data = {
'Name': ['Alice', 'Bob', 'Charlie'],
'Age': [25, 30, 35],
'City': ['New York', 'Los Angeles', 'Chicago']
}

df = pd.DataFrame(data)
print(df)

4. DataFrame 基本操作

4.1 查看数据

  • 头部和尾部:使用 head()tail() 方法可以查看数据的前几行和最后几行。
1
2
print(df.head())  # 默认前5行
print(df.tail(2)) # 最后2行
  • 数据概览:使用 info()describe() 方法可以获取 DataFrame 的基本信息和统计摘要。
1
2
print(df.info())  # 数据结构信息
print(df.describe()) # 数值列的统计信息

4.2 选择数据

  • 选择列:可以通过列名选择特定列。
1
2
print(df['Name'])  # 返回 Name 列
print(df[['Name', 'Age']]) # 返回 Name 和 Age 列
  • 选择行:使用 lociloc 方法选择特定的行。
1
2
3
4
5
# 根据标签选择
print(df.loc[0]) # 返回第0行

# 根据索引选择
print(df.iloc[0]) # 返回第0行

4.3 条件筛选

Pandas 提供了强大的条件筛选功能。

1
2
3
# 筛选 Age 大于 30 的行
filtered_df = df[df['Age'] > 30]
print(filtered_df)

5. 数据清理

5.1 缺失值处理

  • 检测缺失值:使用 isnull()notnull() 可以检测缺失值。
1
print(df.isnull())  # 检查所有数据的缺失情况
  • 填充缺失值:使用 fillna() 方法可以填充缺失值。
1
df_filled = df.fillna(0)  # 将缺失值填充为 0
  • 删除缺失值:使用 dropna() 方法可以删除含有缺失值的行或列。
1
df_dropped = df.dropna()  # 删除含有缺失值的行

5.2 数据转换

  • 修改数据类型:使用 astype() 可以转换数据类型。
1
df['Age'] = df['Age'].astype(float)
  • 字符串操作:可以使用 .str 访问字符串方法。
1
df['Name'] = df['Name'].str.upper()  # 将 Name 列的值全部转换为大写

6. 数据分析

6.1 排序

使用 sort_values() 方法可以对 DataFrame 进行排序。

1
df_sorted = df.sort_values(by='Age', ascending=False)  # 按 Age 降序排列

6.2 分组操作

使用 groupby() 方法可以对数据进行分组,并对每组数据进行聚合操作。

1
2
grouped = df.groupby('City')['Age'].mean()  # 按 City 分组,并计算 Age 的平均值
print(grouped)

6.3 合并数据

Pandas 提供了 merge()concat()join() 等方法来合并数据。

1
2
3
4
5
6
# 合并两个 DataFrame
df1 = pd.DataFrame({'key': ['A', 'B', 'C'], 'value': [1, 2, 3]})
df2 = pd.DataFrame({'key': ['A', 'B', 'D'], 'value': [4, 5, 6]})

merged_df = pd.merge(df1, df2, on='key', how='inner') # 内连接
print(merged_df)

7. 数据输入输出

  • 读取 CSV 文件:使用 read_csv() 方法可以从 CSV 文件读取数据。
1
df = pd.read_csv('data.csv')
  • 写入 文件:使用 to_csv() 方法可以将 DataFrame 保存为 CSV 文件。
1
df.to_csv('output.csv', index=False)

8. 可视化

Pandas 可以与 Matplotlib、Seaborn 等库结合使用来生成图表。

1
2
3
4
import matplotlib.pyplot as plt

df['Age'].plot(kind='hist')
plt.show()

9. 高级功能

9.1 透视表

使用 pivot_table() 方法可以生成透视表。

1
2
pivot = df.pivot_table(values='Age', index='City', columns='Name', aggfunc='mean')
print(pivot)

9.2 时间序列分析

Pandas 提供了强大的时间序列处理功能。

1
2
3
4
5
6
7
8
# 将列转换为日期格式
df['Date'] = pd.to_datetime(df['Date'])

# 设置索引为日期
df.set_index('Date', inplace=True)

# 进行重采样
df_resampled = df.resample('M').mean() # 按月重采样

10. 实用技巧

  • 链式操作:Pandas 支持链式操作,可以将多个操作链式连接在一起,代码更简洁。
1
result = df.dropna().sort_values(by='Age').reset_index(drop=True)
  • 使用 .apply() 函数apply() 函数可以对 Series 或 DataFrame 应用自定义函数。
1
df['Age_plus_one'] = df['Age'].apply(lambda x: x + 1)

以上是 Pandas 模块的简要详解,Pandas 功能丰富,在实际应用中还可以深入学习更多高级用法。

简介

  • python3中selenium模块相关笔记

python3 selenium模块 详解

Selenium 是一个流行的 Web 测试和自动化工具,通常用于通过编程方式控制浏览器执行各种任务。Selenium 提供了多种语言绑定,其中之一是 Python。通过 selenium 模块,你可以用 Python 编写脚本来自动化浏览器的操作,如填表、点击按钮、抓取数据等。

下面是 Selenium 模块的详细介绍,包括安装、基本用法以及常用功能。

1. 安装 Selenium

要在 Python 中使用 Selenium,首先需要安装它:

1
pip install selenium

2. 基本用法

在使用 Selenium 之前,你还需要下载一个适用于你所用浏览器的 WebDriver。例如,如果你使用 Chrome 浏览器,你需要下载 ChromeDriver。

2.1 导入模块并设置 WebDriver

1
2
3
4
5
6
7
from selenium import webdriver

# 设置 Chrome WebDriver 的路径
driver = webdriver.Chrome(executable_path='/path/to/chromedriver')

# 打开一个网页
driver.get('https://www.example.com')

2.2 查找元素

Selenium 提供多种方法来查找页面中的元素:

  • find_element_by_id(id)
  • find_element_by_name(name)
  • find_element_by_xpath(xpath)
  • find_element_by_css_selector(css_selector)
  • find_element_by_tag_name(tag_name)
  • find_element_by_class_name(class_name)
1
2
3
4
5
6
# 查找元素
element = driver.find_element_by_id('element_id')

# 对元素进行操作
element.click() # 点击元素
element.send_keys('text') # 输入文本

2.3 与页面交互

  • 点击按钮:
1
2
button = driver.find_element_by_xpath('//button[@id="submit"]')
button.click()
  • 输入文本:
1
2
input_box = driver.find_element_by_name('q')
input_box.send_keys('Selenium Python')
  • 获取文本内容:
1
2
text = driver.find_element_by_tag_name('h1').text
print(text)

3. 常用功能

3.1 等待页面加载

有时页面元素需要时间加载,Selenium 提供了两种等待机制:

  • 隐式等待: 在设置的时间内等待元素加载完成。
1
driver.implicitly_wait(10)  # 等待最多10秒
  • 显式等待: 明确等待某个条件满足。
1
2
3
4
5
6
7
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, 'myElement'))
)

3.2 处理弹窗

可以用 switch_to.alert 来处理 JavaScript 弹窗:

1
2
3
alert = driver.switch_to.alert
alert.accept() # 接受弹窗
alert.dismiss() # 关闭弹窗

3.3 处理多窗口

Selenium 允许在多个窗口或标签页之间切换:

1
2
3
4
5
6
7
8
# 获取当前窗口句柄
main_window = driver.current_window_handle

# 获取所有窗口句柄
windows = driver.window_handles

# 切换到新窗口
driver.switch_to.window(windows[1])

3.4 截图

可以用 save_screenshot 方法截图:

1
driver.save_screenshot('screenshot.png')

4. 关闭浏览器

完成操作后,应该关闭浏览器:

1
driver.quit()

5. 完整示例

以下是一个完整的示例,展示如何使用 Selenium 进行简单的搜索操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from selenium import webdriver
from selenium.webdriver.common.keys import Keys

# 设置 WebDriver
driver = webdriver.Chrome(executable_path='/path/to/chromedriver')

# 打开 Google
driver.get('https://www.google.com')

# 查找搜索框并输入内容
search_box = driver.find_element_by_name('q')
search_box.send_keys('Selenium Python')
search_box.send_keys(Keys.RETURN)

# 等待搜索结果页面加载并获取结果
driver.implicitly_wait(10)
results = driver.find_elements_by_xpath('//h3')

for result in results:
print(result.text)

# 关闭浏览器
driver.quit()

6. 高级功能

Selenium 还支持处理复杂的场景,如文件上传、拖放、iframe 操作等。了解这些功能可以通过官方文档或其他高级教程。

7. 参考文档

你可以在 Selenium 官方文档 中找到更多详细的内容和使用示例。

python3 selenium.WebDriver类 详解

WebDriver 类是 Selenium 中的核心类之一,用于控制和与浏览器交互。通过 WebDriver 类,您可以启动和操作各种浏览器(如 Chrome、Firefox、Safari 等),执行诸如打开网页、查找元素、模拟用户输入、点击、截屏等操作。

以下是 WebDriver 类的详细解释:

1. WebDriver 类简介

WebDriver 是一个抽象类,用于定义所有浏览器驱动程序(如 ChromeDriverFirefoxDriver 等)必须实现的接口。通过 WebDriver 类,可以执行一系列浏览器操作,如导航、窗口管理、页面交互等。

2. 浏览器驱动初始化

使用 WebDriver 类时,通常需要实例化一个特定浏览器的驱动程序。以下是几个常见的浏览器驱动初始化方式:

1
2
3
4
5
6
7
8
9
10
11
12
13
from selenium import webdriver

# 初始化 Chrome 浏览器驱动
driver = webdriver.Chrome()

# 初始化 Firefox 浏览器驱动
driver = webdriver.Firefox()

# 初始化 Safari 浏览器驱动
driver = webdriver.Safari()

# 初始化 Edge 浏览器驱动
driver = webdriver.Edge()

3. 常用方法与属性

WebDriver 类提供了许多方法和属性,用于控制和操作浏览器。以下是一些常用的方法和属性:

3.1 页面导航

  • get(url): 导航到指定的 URL。

    1
    driver.get("https://www.example.com")
  • current_url: 返回当前页面的 URL。

    1
    current_page_url = driver.current_url
  • title: 返回当前页面的标题。

    1
    page_title = driver.title
  • back(): 模拟浏览器的后退按钮。

    1
    driver.back()
  • forward(): 模拟浏览器的前进按钮。

    1
    driver.forward()
  • refresh(): 刷新当前页面。

    1
    driver.refresh()

3.2 元素查找

  • find_element_by_id(id): 根据元素的 id 查找元素。

    1
    element = driver.find_element_by_id("element-id")
  • find_element_by_name(name): 根据元素的 name 属性查找元素。

    1
    element = driver.find_element_by_name("element-name")
  • find_element_by_xpath(xpath): 根据 XPath 表达式查找元素。

    1
    element = driver.find_element_by_xpath("//div[@class='example']")
  • find_element_by_css_selector(selector): 根据 CSS 选择器查找元素。

    1
    element = driver.find_element_by_css_selector(".example-class")
  • find_elements_by_*: 对应于 find_element_by_* 的方法,用于查找多个符合条件的元素,返回一个元素列表。

3.3 浏览器窗口管理

  • maximize_window(): 最大化浏览器窗口。

    1
    driver.maximize_window()
  • minimize_window(): 最小化浏览器窗口。

    1
    driver.minimize_window()
  • set_window_size(width, height): 设置浏览器窗口大小。

    1
    driver.set_window_size(1024, 768)
  • get_window_size(): 获取当前窗口大小。

    1
    size = driver.get_window_size()
  • switch_to.window(window_name): 切换到指定的窗口或标签页。

    1
    driver.switch_to.window(driver.window_handles[1])

3.4 框架和窗口切换

  • switch_to.frame(frame_reference): 切换到指定的 iframe 或 frame。

    1
    driver.switch_to.frame("frame-name")
  • switch_to.default_content(): 退出 iframe 或 frame,返回到主页面内容。

    1
    driver.switch_to.default_content()

3.5 警告和弹出框处理

  • switch_to.alert: 切换到浏览器警告对话框(alert)。

    1
    2
    3
    alert = driver.switch_to.alert
    alert.accept() # 确认警告
    alert.dismiss() # 取消警告

3.6 执行 JavaScript

  • execute_script(script, *args): 在页面上执行 JavaScript 脚本。

    1
    driver.execute_script("alert('Hello, world!')")

3.7 截屏

  • save_screenshot(filename): 截取当前窗口并保存为文件。

    1
    driver.save_screenshot("screenshot.png")

4. 关闭与退出

  • close(): 关闭当前窗口。如果这是唯一的窗口,则会退出 WebDriver 会话。

    1
    driver.close()
  • quit(): 关闭所有关联的窗口,并退出 WebDriver 会话。

    1
    driver.quit()

5. 等待

在 WebDriver 中,等待是一个非常重要的概念,尤其是在处理动态加载的网页内容时。Selenium 提供了两种等待方式:

5.1 隐式等待

设置一个全局等待时间,WebDriver 会在查找元素时,轮询等待元素在指定时间内加载完成。

1
driver.implicitly_wait(10)  # 等待最多10秒

5.2 显式等待

显式等待指定某个条件,在指定时间内等待该条件满足。如果条件在超时时间内满足,继续执行;否则抛出异常。

1
2
3
4
5
6
7
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "element-id"))
)

6. 异常处理

使用 WebDriver 时,可能会遇到各种异常,如元素未找到、超时、无效的 URL 等。Selenium 提供了一些常见的异常类:

  • NoSuchElementException: 元素未找到。
  • TimeoutException: 操作超时。
  • WebDriverException: 一般性的 WebDriver 错误。

可以通过异常处理机制来捕获和处理这些错误。

1
2
3
4
5
6
from selenium.common.exceptions import NoSuchElementException

try:
driver.find_element_by_id("non-existent-id")
except NoSuchElementException:
print("Element not found!")

7. 示例代码

以下是一个简单的示例,展示了如何使用 WebDriver 类打开网页、查找元素并与之交互。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from selenium import webdriver

# 初始化 Chrome 浏览器
driver = webdriver.Chrome()

# 打开网页
driver.get("https://www.example.com")

# 查找元素并与之交互
search_box = driver.find_element_by_name("q")
search_box.send_keys("Selenium WebDriver")
search_box.submit()

# 等待页面加载完成
driver.implicitly_wait(5)

# 获取页面标题
print(driver.title)

# 关闭浏览器
driver.quit()

总结

WebDriver 类是 Selenium 的核心,提供了丰富的功能来自动化浏览器操作。掌握 WebDriver 的各种方法和属性,是进行 Web 自动化测试的基础。

python3 WebDriver.get()函数 详解

WebDriver.get() 是 Selenium WebDriver 的一个函数,用于让 WebDriver 导航到指定的 URL(即加载网页)。该函数是自动化浏览器操作的基础之一。以下是 WebDriver.get() 函数的详细说明:

1. 函数定义

1
webdriver.get(url)
  • webdriver 是你初始化的浏览器对象(例如 Chrome、Firefox 等)。
  • url 是你希望 WebDriver 加载的网页的 URL,它必须是一个字符串。

2. 参数说明

  • url: 这是一个字符串,表示你想让 WebDriver 打开的网页地址。该 URL 必须以 http://https:// 开头。如果没有指定协议,WebDriver 将不会加载页面,并且可能抛出异常。

3. 返回值

  • 该方法没有返回值。WebDriver 将会打开指定的 URL,并在页面完全加载后继续执行后续代码。

4. 常见用途

  • 打开网页: 这是 WebDriver.get() 最常见的用途,用于在浏览器中导航到特定的网页。

    1
    2
    3
    4
    5
    6
    7
    from selenium import webdriver

    # 初始化 WebDriver
    driver = webdriver.Chrome()

    # 打开网页
    driver.get("https://www.example.com")
  • 与其他 WebDriver 操作结合: 在加载页面后,通常会执行其他操作,如查找元素、执行 JavaScript 等。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    from selenium import webdriver

    driver = webdriver.Chrome()
    driver.get("https://www.example.com")

    # 查找页面中的元素
    element = driver.find_element_by_id("example-id")

    # 执行其他操作
    element.click()

5. 注意事项

  • 等待页面加载: WebDriver.get() 会等待页面的完全加载,即等待所有同步加载的资源(HTML、CSS、JavaScript 等)都加载完成后,才会继续执行下一行代码。但是,某些动态内容(例如通过 AJAX 加载的数据)可能需要手动等待。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC

    driver.get("https://www.example.com")

    # 等待某个元素加载完成
    WebDriverWait(driver, 10).until(
    EC.presence_of_element_located(("id", "example-id"))
    )
  • 异常处理: 如果给定的 URL 格式不正确,或由于其他原因无法加载页面,WebDriver 可能会抛出异常(如 WebDriverException)。在实际应用中,可以通过异常处理机制捕获并处理这些错误。

    1
    2
    3
    4
    try:
    driver.get("invalid-url")
    except Exception as e:
    print(f"An error occurred: {e}")

6. 关闭 WebDriver

在使用完 WebDriver 后,应该调用 quit() 方法来关闭浏览器并释放资源。

1
driver.quit()

总结

WebDriver.get() 是 Selenium WebDriver 中非常基本且重要的函数,用于导航到指定网页。理解和正确使用这个方法,是自动化浏览器操作的基础。

python3 WebDriver.delete_all_cookies()函数 详解

WebDriver.delete_all_cookies() 是 Selenium WebDriver 中的一个函数,用于删除当前会话中的所有 cookies。下面是对该函数的详细解释:

功能

delete_all_cookies() 方法的主要功能是在自动化测试过程中清除浏览器中所有的 cookies。Cookies 是存储在浏览器中的小数据文件,通常用于保持用户登录状态、存储用户偏好等。在某些测试场景中,可能需要删除这些 cookies 以确保测试的独立性和一致性。

用法

1
2
3
4
5
6
7
8
9
10
11
12
from selenium import webdriver

# 创建 WebDriver 实例
driver = webdriver.Chrome()

# 打开某个网页
driver.get("https://www.example.com")

# 删除所有 cookies
driver.delete_all_cookies()

# 继续执行其他操作

应用场景

  • 清除会话数据: 当你希望从一个干净的状态开始测试时,可以使用 delete_all_cookies() 来清除所有的 session 信息。
  • 模拟不同用户登录: 在测试不同用户登录时,删除 cookies 可以防止前一个用户的会话信息干扰到下一个用户。
  • 重置浏览器状态: 在多步骤的测试中,删除 cookies 可以帮助重置浏览器状态,以确保每个步骤都从同一初始状态开始。

注意事项

  • 这个方法会删除当前会话的所有 cookies,并且在调用 delete_all_cookies() 之后,如果页面依赖 cookies 工作,可能需要重新加载页面或者重新设置 cookies。
  • 删除 cookies 不会影响浏览器的历史记录或缓存,只会影响 cookies。

常见问题

  • 删除后无效: 如果删除 cookies 后仍然看到之前的数据,可能是因为浏览器的缓存问题,建议同时清除缓存。
  • 权限问题: 某些 cookies 可能由于安全设置而无法删除,这通常涉及到跨域或安全标志的 cookies。

通过使用 delete_all_cookies(),你可以确保在不同的测试场景中拥有一个干净的环境,从而提高测试的准确性和可靠性。

python3 WebDriver.find_elements()函数 详解

WebDriver.find_elements() 是 Selenium WebDriver 中用于查找网页元素的一个函数。它返回符合特定定位策略的所有元素列表。如果没有找到任何元素,则返回空列表。

函数签名

1
elements = driver.find_elements(by=By.XPATH, value="//tag[@attribute='value']")

参数

  • by: 用于指定查找元素的方式,通常使用 By 类提供的常量,例如 By.ID, By.NAME, By.XPATH 等。
  • value: 一个字符串,指定如何根据 by 参数查找元素的值。例如,如果 by=By.ID,那么 value 就是对应的元素 id 值。

常用的 By 定位方式

  • By.ID: 通过元素的 id 属性定位元素。
  • By.NAME: 通过元素的 name 属性定位元素。
  • By.CLASS_NAME: 通过元素的 class 属性定位元素。
  • By.TAG_NAME: 通过元素的标签名定位元素。
  • By.LINK_TEXT: 通过元素的文本内容(超链接)定位元素。
  • By.PARTIAL_LINK_TEXT: 通过部分文本内容定位超链接。
  • By.XPATH: 通过 XPath 表达式定位元素。
  • By.CSS_SELECTOR: 通过 CSS 选择器定位元素。

返回值

  • List[WebElement]: 由所有匹配元素组成的列表。如果没有找到元素,返回空列表。

示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from selenium import webdriver
from selenium.webdriver.common.by import By

# 初始化 WebDriver(比如使用 Chrome 浏览器)
driver = webdriver.Chrome()

# 打开一个网址
driver.get("https://www.example.com")

# 使用 find_elements() 查找元素列表
elements = driver.find_elements(By.CLASS_NAME, "example-class")

# 遍历并操作元素
for element in elements:
print(element.text)

# 关闭 WebDriver
driver.quit()

注意事项

  • find_element() 不同,find_elements() 不会抛出 NoSuchElementException 异常。如果没有找到元素,返回的是一个空列表。
  • find_elements() 查找所有符合条件的元素,而 find_element() 仅返回第一个匹配的元素。

通过 find_elements(),可以轻松地处理网页中的多个相似元素,比如同一类的按钮、表单元素等。

简介

  • cmake官方文档: MasteringCMake 阅读笔记

目录结构

  • CMake在构建项目时有两个主要的目录: 源代码目录和二进制目录
    • 源代码目录是存放项目源代码的位置
    • 二进制目录,有时候也成为build目录,是CMake存放最终对象文件,库和可执行文件的位置。
  • CMake不会向源代码目录写任何文件,只会向二进制目录写文件。

基础用法

  • CMake用各种各样的本地开发工具,将一个或多个CMakeLists 文件作为输入,并生成项目文件或者Makefile使用
  • 下面是典型的CMake处理流程
    • 项目定义一个或多个CMakeLists文件
    • CMake配置并生成项目文件
    • 用户按需使用本地开发工具构建项目

CMakeLists文件

  • CMakeLists文件是包含使用CMake语言描述项目的文本文件。
  • CMake语言表示为一系列的注释,命令和变量。
  • CMake为什么要有自己的语言?
    • 因为CMake如果依赖于其他语言,例如Python,就需要在使用CMake时安装其他语言。
    • 有CMake语言能够更高效,更方便。

CMake中的Hello World

  • 示例

    1
    2
    3
    cmake_minimum_required(VERSION 3.20)
    project(Hello)
    add_executable(Hello Hello.c)
  • CMakeLists文件第一行总会是 cmake_minimum_requried.这使得CMake可以使用指定的版本。

  • 第二行应该是 project 命令。这个命令设置项目的名字,也可以指定其他的参数,例如语言,版本。

  • 最后使用 add_executable 命令用这些给定的源代码文件生成项目的可执行对象。

为CMake指定编译器

  • 环境变量 CC 用来指定 C编译器

  • 环境变量 CXX 用来指定 C++编译器

  • 可以在命令行中通过使用 -DCMAKE_CXX_COMPILER=cl 来指定编译器

  • 设置 LDFLAGS 用来初始化 链接参数

  • 设置 CXXFLAGS 用来初始化 CMAKE_CXX_FLAGS

  • 设置 CFLAGS 用来初始化 CMAKE_C_FLAGS

构建配置

  • 构建配置允许以不同的方式构建项目。CMake默认支持的方式有: Debug, Release, MinSizeRel, RelWithDebInfo
    • Debug: 打开了基本的调试符号
    • Release: 打开了基本的优化
    • MinSizeRel: 产生最小的,但不一定是最快的目标文件
    • RelWithDebInfo: 既有调试信息,也开启了优化的目标文件

简介

输出文件名和行号

  • 使用宏,例如SPDLOG_INFO

使用宏函数输出的日志也写入到文件

  • 使用函数 spdlog::set_default_logger();
  • 示例如下
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    static void InitLogger()
    {
    //创建控制台日志记录器
    auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
    console_sink->set_level(spdlog::level::debug);

    console_sink->set_pattern("[%Y-%m-%d %H:%M:%S.%e][thread %t][%s:%#][%l]: %v");

    // 创建文件日志记录器: 滚动记录,最大文件5M,文件数量100个
    std::string log_path = ROOT_PATH;
    log_path += "logs/rotating.txt";
    auto rotating_sink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>(log_path, 1048576 * 5, 100);

    //同步记录器,
    std::vector<spdlog::sink_ptr> sinks{ console_sink, rotating_sink };
    auto logger = std::make_shared<spdlog::logger>("logger", sinks.begin(), sinks.end());
    spdlog::register_logger(logger); //注册为全局日志,通过log_write访问;

    // 宏相关配置
    spdlog::set_default_logger(logger);
    spdlog::set_pattern("[%Y-%m-%d %H:%M:%S.%e][thread %t][%s:%#][%l]: %v");
    spdlog::set_level(spdlog::level::warn);
    spdlog::flush_every(std::chrono::seconds(3)); //每3s刷新一次
    }

核心概念

  • logger: 日志对象,每个日志内包含一个sink组成的vector,每个sink可以分别设置优先级,logger本身也可设置优先级。

  • sink: 直译是水槽,实际上是引流的对象或者可以认为是输出目标,spdlog库内置了多种不同类型的logger可供选择

  • formatter: 格式化对象,绝大部分情况下spdlog默认的格式就足够用了,但是如果有个性化需求,可以进行自定义格式

  • level: 日志级别,不同的日志库可能会有不同的设置,但是基本情况下都会有debug,info,warn,error等级别划分来处理不同的情况,具体各个级别的情况可以根据自己的实际情况选取

  • 逻辑关系

    • 每个logger包含一个vector,该vector由一个或者多个 std::shared_ptr 组成,logger的每条日志都会调用sink对象,由sink对象按照formatter的格式输出到指定的地方(有可能是控制台,文件等)

formatter

  • formatter也即是格式化对象,用于控制日志的输出格式,spdlog自带了默认的formatter,一般情况下,我们无需任何修改,直接使用即可。需要注意的是,每个sink会有一个formatter
  • 默认formatter的格式为: [日期时间][logger名][log级别]log内容
    1
    2
    3
    4
    5
    [2022-10-13 17:00:55.795] [service] [debug] found env XXXXXXX : true
    [2022-10-13 17:00:55.795] [func_config] [debug] kafka_brokers : localhost:9092
    [2022-10-13 17:00:55.795] [func_config] [debug] kafka_main_topic : kafka_test
    [2022-10-13 17:00:55.795] [func_config] [debug] kafka_partition_value : -1
    [2022-10-13 17:00:55.795] [service] [info] initialized

sink

  • 每个sink对应着一个输出目标和输出格式,它内部包含一个formatter,输出目标可以是控制台,文件等地方。

  • 所有的sink都在命名空间spdlog::sinks下,可以自行探索

  • spdlog中创建控制台sink非常简单,该方式创建的sink会输出到命令行终端,且是彩色的。后缀的 _mt 代表多线程, _st 代表单线程

    1
    auto sink1 = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
  • 文件sink的类型有很多,这里展示几种经典类型

    1
    2
    3
    4
    5
    auto sink1 = std::make_shared<spdlog::sinks::basic_file_sink_mt>(log_file_name);//最简单的文件sink,只需要指定文件名

    auto sink2 = std::make_shared<spdlog::sinks::daily_file_sink_mt>(log_file_name, path, 14, 22);//每天的14点22分在path下创建新的文件

    auto sink3 = std::make_shared<spdlog::sinks::rotating_file_sink_mt>(log_file_name, 1024 * 1024 * 10, 100, false);//轮转文件,一个文件满了会写到下一个文件,第二个参数是单文件大小上限,第三个参数是文件数量最大值
  • 其他sink

    • ostream_sink
    • syslog_sink
  • sink的flush问题

    • 创建好sink后建议设置flush方式,否则可能无法立刻在文件中看到logger的内容
    • 以下为两种重要的flush方式设置(直接设置全局)
      1
      2
      spdlog::flush_every(std::chrono::seconds(1));
      spdlog::flush_on(spdlog::level::debug);

logger

  • 日志对象,每个logger内容包含了一个vector用于存放sink,每个sink都是互相独立

  • 因此一个日志对象在输出日志时可以同时输出到控制台和文件等位置

  • 如果整个项目中只需要一个logger,spdlog提供了最为便捷的logger,注意,该logger在全局公用,输出到控制台,多线程,彩色。

    1
    2
    //Use the default logger (stdout, multi-threaded, colored)
    spdlog::info("Hello, {}!", "World");
  • 创建特定的logger

    • 大部分情况下默认logger是不够用的,因为我们可能需要做不同模块各自的logger,可能需要logger输出到文件进行持久化,所以创建logger是很很重要的一件事。
  • 直接创建

    • 与创建sink类似,我们可以非常便捷的创建logger。
    • 由于大部分时候一个logger只会有一个sink,所以spdlog提供了创建logger的接口并封装了创建sink的过程
      1
      2
      auto console = spdlog::stdout_color_mt("some_unique_name");//一个输出到控制台的彩色多线程logger,可以指定名字
      auto file_logger = spdlog::rotating_logger_mt("file_logger", "logs/mylogfile", 1048576 * 5, 3);//一个输出到指定文件的轮转文件logger,后面的参数指定了文件的信息
  • 组合sinks方式创建

    • 有时候,单sink的logger不够用,那么可以先创建sink的vector,然后使用sinks_vector创建vector
    • 以下示例中,首先创建了sink的vector,然后创建了两个sink并放入vector,最后使用该vector创建了logger,其中 set_level 的过程不是必须的, register_logger 一般是必须的,否则只能在创建logger的地方使用该logger
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      std::vector<spdlog::sink_ptr> sinks;

      auto sink1 = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
      sink1->set_level(MyLoggers::getGlobalLevel());
      sinks.push_back(sink1);

      auto sink2 = std::make_shared<spdlog::sinks::rotating_file_sink_mt>(log_file_name, 1024 * 1024 * 10, 100, false);
      sink2->set_level(spdlog::level::debug);
      sinks.push_back(sink2);

      auto logger = std::make_shared<spdlog::logger>("logger_name", begin(sinks), end(sinks));
      logger->set_level(spdlog::level::debug);
      spdlog::register_logger(logger);
  • logger的注册与获取

    • 在一个地方创建了logger却智能在该处使用肯定是不好的,所以spdlog提供了全局注册和获取logger,我们只需要在某处先创建logger并注册,那么后面再其他地方使用时直接获取就可以了
    • 注册: spdlog::register_logger()
    • 获取: spdlog::get()
      1
      2
      //上面的代码中我们注册了一个logger,名字是logger_name,接下来尝试获取
      auto logger = MyLoggers::getLogger("logger_name");

logger的使用

  • logger的默认level是info,如果处于开发换进给或者生产环境,绘制需要debug级别以上,可以设置logger的级别

    1
    logger->set_level(spdlog::level::debug);
  • 可以设置全局logger级别

    1
    spdlog::set_level(spdlog::level::warn);
  • 可以设置sink级别的logger

    1
    sink1->set_level(spdlog::level::info);
  • 注意: 一个logger假如有多个sink,那么这些sink分别设置level是可以不同的,但是由于logger本身也有level,所以真正使用时,logger的level如果高于某个sink,会覆盖该sink的level,所以建议此时把logger的level手动设置为debug(默认为info)

1.1 概述

  • 使用方法一:

    • 下载好项目源代码,使用cmake编译,命令:cmake -S . -B build,然后进入build进行make,会获取到一个静态库 libspdlog.a
    • 之后通过包含include下的头文件和链接生成的静态库,使用spdlog
  • 使用方法二:

    • 将头文件和源文件分别添加到相应工程中的头文件和源文件
    • 然后再CMakeLists.txt中添加头文件目录和源文件目录,并且添加一条命令用来编译指定文件:target_compile_definitions(${PROJECT_NAME} PUBLIC SPDLOG_COMPILED_LIB)

1.2 基本用法

  • 输出日志信息到标准输出

    • spdlog::info("This is a log message.{0} {1}", "hello", "world")
    • spdlog::warn("This is a warn message");
    • spdlog::debug("This message should not be displayed");
    • spdlog::set_level(spdlog::level::trace); // set specifice logger's log level
    • spdlog::debug("This message should be displayed, because the level is setted trace");
  • 日志信息输出到文件

    • 创建基础日志文件:
      • #include "spdlog/sinks/basic_file_sink.h"
      • auto my_logger = spdlog::basic_logger_mt("file_logger", "logs/basic-log.txt", true);
      • 创建一个文件为logs/basic-log.txt,并设置输出的消息标识为file_logger的日志文件,通过使用my_logger来操作该日志文件
    • 将日志输出到日志文件中:
      • my_logger->info("Helo Info");
  • 输出行号:

    • SPDLOG_DEBUG("some debug message about program: {}", "robot");

spdlog spdlog::get()函数 详解

spdlog 是一个快速的 C++ 日志库,广泛用于高效日志记录。spdlog::get() 函数用于获取已经创建的日志记录器(logger)的共享指针。如果指定名称的日志记录器不存在,它会返回 nullptr

1. 函数定义

1
std::shared_ptr<spdlog::logger> spdlog::get(const std::string &name);

2. 参数说明

  • name: 一个 std::string 类型的参数,表示需要获取的日志记录器的名称。

3. 返回值

  • std::shared_ptr<spdlog::logger>: 返回一个指向指定名称的日志记录器的共享指针。如果指定名称的日志记录器未找到,则返回 nullptr

4. 使用场景

spdlog::get() 通常用于在应用程序的不同模块中共享同一个日志记录器。比如,你在主模块中创建了一个名为 “my_logger” 的日志记录器,之后可以在其他模块中通过 spdlog::get("my_logger") 获取同一个记录器,而无需重新创建。

5. 示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <spdlog/spdlog.h>
#include <spdlog/sinks/basic_file_sink.h>

int main() {
// 创建一个名为 "file_logger" 的日志记录器
auto logger = spdlog::basic_logger_mt("file_logger", "logs.txt");

// 使用记录器进行日志记录
logger->info("This is an info message");

// 在其他地方获取并使用相同的记录器
auto same_logger = spdlog::get("file_logger");
if (same_logger) {
same_logger->warn("This is a warning message from the same logger");
} else {
spdlog::error("Logger not found");
}

return 0;
}

6. 注意事项

  • spdlog::get() 只返回已经通过 spdlog::register_logger() 或者 spdlog::basic_logger_mt() 等方法注册过的日志记录器。如果未注册过,返回的会是 nullptr
  • spdlog::get() 函数是线程安全的,因此可以在多线程环境中安全使用。

通过 spdlog::get(),你可以在不同模块中灵活地获取和使用日志记录器,确保日志管理的一致性。

简介

  • VSCode下C++程序的调试的配置文件是launch.json。这篇文章是关于launch.json文件的使用笔记,包括常见的参数,常用技巧和常见错误及其解决方法。

windows 程序调试阻塞,出现 unable to start Microsoft Visual Debug Console.

  • 这个是因为程序输出需要在命令窗口中,在launch.json中console参数是设置命令窗口的启动属性。如果设置了 externalTerminal 则会出现问题。

  • 解决方法

    • 将console的值设置为 integratedTerminal

console 参数 详解

  • console: Where to launch the debug target. Defaults to ‘internalConsole’ if not defined.

  • console: 需要调试的程序运行的地方。如果没有定义,默认为 internalConsole

  • console的值有:

    • externalTerminal:
      • Console applications will be launched in an external terminal window. The window will be reused in relaunch scenarios and will not automatically disappear when the application exits.
      • 控制台应用程序将在外部控制台窗口中启动。这个窗口将在程序再次启动时被重复使用,并且不会随着程序退出自动退出。
    • integratedTerminal
      • VS Code’s integrated terminal.
      • VSCode的集成终端
    • internalConsole
      • Output to the VS Code Debug Console. This doesn’t support reading console input (ex:’std::cin’ or ‘scanf’).
      • 输出到VSCode调试窗口。这个不支持从窗口读取数据,例如 std::cin或 scanf
    • newExternalWindow
      • Console applications will be launched in their own external console window which will end when the application stops. Non-console applications will run without a terminal, and stdout/stderr will be ignored.
      • 控制台应用程序将在其自己的外部控制台窗口中启动,该窗口将在应用程序停止时结束。非控制台应用程序在没有终端且标准输出和标准错误输出被忽略的情况下运行。

简介

  • 本书主要介绍如何使用Qt进行C++应用程序开发。
  • Qt实际上是一套应用程序开发类库,Qt类库由许多模块组成,例如核心的GUI组件模块Qt Widget,用于数据库访问的Qt SQL模块,用于二维图表显示的Qt Charts模块,用于数据三位显示的Qt Data Visualization模块,用于网络编程的Qt Network模块等。

第一章 认识Qt

1.1 Qt简介

  • C++是一种通用的标准编程语言,使用任何编辑器都可以编写C++源程序,然后利用C++编译器对程序进行编译,就可以生成可执行的程序。
  • 为了方便进行C++程序的编写和编译,有各种综合开发环境(Integrated Developing Environment, IDE),例如Visual Studio就是Windows平台上常见的编写C++程序的IDE。一个IDE不仅提供程序的编辑和编译,一般还提供一套基本类库,用于提供支持平台应用程序开发的各种基本类,例如Visual Studio使用MFC进行Windows平台的应用程序开发。
  • Qt是一套应用程序开发类库,但是与MFC不同,Qt是跨平台的开发类库。Qt支持PC和服务器的平台,包括Windows,Linux,macOS等,还支持移动和嵌入式操作系统,例如IOS,Embedded Linux,Andriod,WinRT等。跨平台意味着只需要编写一次程序,在不同平台上无需改动或只需要少许改动后在编译,就可以形成不同平台上运行的版本。

1.2 Qt的获取和安装

1.2.1 Qt的许可类型

  • Qt的许可类型分为商业许可和开源许可,开源许可又分为LGPLV3和GPLV2/GPLV3.

1.2.2 Qt的版本

  • Qt的版本更新比较快,且版本更新时会新增一些类或者停止维护一些以前版本的类。如果不是为了维护用旧版本编写的程序,一定要选用最新版本的Qt进行程序开发。

1.2.3 Qt的下载和安装

  • 从Qt官网可以下载最新版本的Qt软件。根据开发项目的不同,Qt分为桌面和移动设备应用开发,嵌入式设备开发两大类不同的安装包。

    • 桌面和移动设备应用开发就是开发在PC,服务器,手机,平板电脑等设备上运行的程序,操作系统平台可以是Windows,Linux,macOS,Andriod等。
    • 嵌入式设备开发是针对具体的嵌入式设备来开发应用程序,例如物联网设备,汽车电子设备,医疗设备等特定的嵌入式设备。
  • Qt的安装包分为在线安装包和离线安装包,为便于重复安装,最好下载离线安装包。

  • 在安装过程中会出现安装选项设置页面,在这个页面里选择需要安装的模块。这些模块包括内容如下

    • MinGW 编译器模块。MinGW是Minimalist GNU For Windows的缩写,MinGW是Windows平台上使用的GNU工具集导入库的集合。
    • 用于UWP编译的模块。UWP是Windows 10中Universal Windows Platform的简称,有不同编译器类型的UWP
    • 用于Windows平台上的MSVC编译器模块。要安装MSVC编译器的模块,需要计算机上已经安装相应版本的Visual Studio
    • 用于Andriod平台的模块,例如 Andriod x86和Android ARMv7
    • Sources是Qt的源程序类
    • Qt Charts是二维图标模块,用于绘制柱状图,饼图,曲线图等常用二维图表
    • Qt Data Visualization是三维数据图表模块,用于数据的三维显示,例如散点的三维空间分布,三维曲面等
    • Qt Purchsing,Qt WebEngine, Qt Network Auth(TP)等其他模块,括号里的TP表示技术预览(Technology Preview)
    • Qt Scritp(Deprecated)是脚本模块,括号里的”Deprecated”表示这是个已经过时的模块
  • “Tools”节点下面是一些工具软件,包括内容如下

    • Qt Creator 是用于Qt程序开发的IDE
    • MinGW 是MinGW编译工具链
    • StrawBerry Perl是一个Perl语言工具
  • 工具软件有

    • Assistant 是一个独立的查看Qt帮助文件的程序,集成在了Qt Creator中
    • Designer 是一个独立的进行窗口,对话框等界面可视化设计的程序。Designer也集成在了Qt Creator中,在Qt Creator中编辑或创建界面文件时,就可以自动打开并进行界面设计。
    • Linguist是一个编辑语言资源文件的程序,在开发多语言界面的应用程序时会用到。
  • 这三个工具软件可独立使用,前两个集成到了Qt Creator里,可在Qt Creator打开。所以Qt的主要工具是Qt Creator。

1.3 Qt Creator初步使用

1.4 编写一个Hello World程序

1.4.1 新建一个项目

  • Qt Creator可以创建多种项目,各类应用程序如下

    • Qt Widgets Application,支持桌面平台的有图形用户界面(Graphic User Interface,GUI)界面的应用程序。GUI的设计完全基于C++语言,采用Qt提供的一套C++类库。
    • Qt Console Application,控制台应用程序,无GUI界面,一般用于学习C/C++语言。
    • Qt Quick Application, 创建可部署的Qt Quick 2应用程序。Qt Quick是Qt支持的一套GUI开发架构,其界面设计采用QML语言,程序架构采用C++语言。利用Qt Quick可以设计非常炫的用户界面,一般用于移动设备或嵌入式设备上无边框的应用程序的设计。
    • Qt Quick Controls 2 Application,创建基于Qt Quick Controls 2组件的可部署的Qt Quick 2应用程序。
    • Qt Canvas 3D Application,创建Qt Canvas 3D QML项目,也是基于QML语言的界面设计,支持3D画布。
  • 界面的基类(base class),有3中基类可以选择

    • QMainWindow 是主窗口类,主窗口具有主菜单栏,工具栏和状态栏,类似于一般的应用程序的主窗口;
    • QWidget 是所有具有可视界面类的基类,选择QWidget创建的界面对各种界面组件都可以支持
    • QDialog 是对话框类,可建立一个基于对话框的界面

第二章 GUI应用程序设计基础

  • 本章深入的介绍Qt Creator设计GUI应用程序的基本方法,包括Qt创建的应用程序项目的 基本组织结构,可视化设计的UI界面文件的原理和运行机制,信号与槽的使用方法,窗体可视化设计的底层原理,应用程序的窗体,组件布局,菜单,工具栏,Actions等常见设计元素的使用方法。

2.1 UI文件设计与运行机制

2.1.1 项目文件组成

  • 一个Widget Application项目包含一下一些文件
    • 项目组织文件 samp2_1.pro,存储项目设置的文件
    • 主程序入口文件main.cpp,实现main()函数的程序文件
    • 窗体界面文件widget.ui,一个XML格式存储的窗体上的元件及其布局的文件
    • widget.h是所设计的窗体类的头文件,widget.cpp是widget.h里定义类的实现文件。在C++里,任何窗体或界面组件都是用类封装的,一个类一般有一个头文件和一个源文件。

2.1.2 项目管理文件

  • 后缀为.pro的文件是项目的管理文件,文件名就是项目的名称

2.1.3 界面文件

  • 后缀为 .ui 的文件是可视化设计的窗体的定义文件,例如 widget.ui
  • 本书后面将成这个集成在Qt Creator中的Qt Designer为 UI设计器,以便与独立运行的Qt Designer区别开来

2.1.4 主函数文件

  • main函数是应用程序的入口。它的主要功能是创建应用程序,创建窗口,显示窗口,并运行从应用程序,开始应用程序的消息循环和事件处理。

2.1.5 窗体相关的文件

  • 为了搞清楚窗体类的定义,以及界面功能的实现原理,香茗居编译后会自动生成一个文件 ui_widget.h,这样对于一个窗体,就有四个文件
    • widget.h 定义窗体类的头文件定义了类Widget
    • widget.cpp Widget类的功能实现源程序文件
    • widget.ui 窗体界面文件,由UI设计器自动生成,存储了窗体上各个组件的属性设置和布局
    • ui_widget.h 编译后,根据窗体上的组件及其属性,信号与槽的关联自动生成的一个类的定义文件,类的名称是Ui_Widget

2.2

2.2.3 信号与槽

  • 信号与槽(Signal & Slot)是Qt编程的基础,也是Qt的一大创新。因为有了信号与槽的编程机制,在Qt中处理界面各个组件的交互操作时变得更加直观和简单。

  • 信号(Signal)就是在特定情况下被发射的事件,例如PushButton最常见的信号就是鼠标单击时发射的clicked()信号,一个ComboBox最常见的信号是选择的列表项变化时发射的CurrentIndexChanged()信号。GUI程序设计的主要内容就是对界面上各组件的信号的相应,只需要知道什么情况下发射哪些信号,合理的去响应和处理这些信号就可以了。

  • 槽(Slot)就是对信号响应的函数。槽就是一个函数,与一般的C++函数是一样的,可以定义在类的任何部分(public, private或protected),可以具有任何参数,也可以被直接调用。槽函数与一般函数不同的是: 槽函数可以与一个信号关联,当信号被发射时,关联的槽函数被自动执行

  • 信号与槽关联是用QObject::connect()函数实现的,其基本格式是:

    1
    QObject::connect(sender, SIGNAL(signal()), reciver, SLOT(slot()));
  • connect()是QObject类的一个静态函数,而QObject是所有Qt类的基类,在实际调用时可以忽略前面的限定符,所以可以直接写为:

    1
    connect(sender, SIGNAL(signal()), reciver, SLOT(slot()));
    • 其中,sender是发射信号的对象的名称,signal()是信号名称。信号可以看作是特殊的函数,需要带括号,有参数时还需要指明参数。receiver是接收信号的对象名称,slot()是槽函数的名称,需要带括号,有参数时还需要指明参数。
    • SIGNAL和SLOT是Qt的宏,用于指明信号和槽,并将它们的参数转换为相应的字符串。例如
      1
      QObject::connect(btnClose, SIGNAL(clicked()), Widget, SLOT(close()));
    • 其作用就是将btnClose按钮的clicked()信号与窗体(Widget)的槽函数close()相关联,这样,当单击btnClose按钮时,就会执行Widget的Close()槽函数。
  • 关于信号与槽的使用,有以下一些规则需要注意

    • 一个信号可以连接多个槽,例如
      1
      2
      connect(spinNum, SIGNAL(valueChanged(int)), this, SLOT(addFun(int)));
      connect(spinNum, SIGNAL(valueChanged(int)), this, SLOT(updateStatus(int)));
      • 这是当一个对象spinNUm的数值发生变化时,所在窗体有两个槽进行响应,一个addFun()用于计算,一个updateStatus()用于更新状态。
      • 当一个信号与多个槽函数关联时,槽函数按照建立连接时的顺序依次执行。
      • 当信号和槽函数带有参数时,在connect()函数里,要写明参数的类型,但可以不写参数名称。
    • 多个信号可以连接同一个槽,例如
      1
      2
      3
      connect(ui->rBtnBlue, SIGNAL(clicked()), this, SLOT(setTextFontColor()));
      connect(ui->rBtnRed, SIGNAL(clicked()), this, SLOG(setTextFontColor()));
      connect(ui->rBtnBlack, SIGNAL(clicked()), this, SLOG(setTextFontColor()));
      • 这样,当任何一个RadioButton被单击时,都会执行setTextFontColor()函数。
    • 一个信号可以连接另外一个信号,例如
      1
      connect(spinNum, SIGNAL(valueChanged(int)), this, SIGNAL(refreshInfo(int)));
      • 这样,当一个信号发射时,也会发射另外一个信号,实现某些特殊的功能。
    • 严格情况下,信号与槽的参数个数和类型需要一致,至少信号的参数不能少于槽的参数。如果不匹配,会出现编译错误或运行错误。
    • 在使用信号与槽的类中,必须在类的定义中加入宏Q_OBJECT
    • 当一个信号被发射时,与其关联的槽函数通常被立即执行,就像正常调用一个函数一样。只有当信号关联的所有槽函数执行完毕后,才会执行发射信号处后面的代码。
  • 信号与槽机制是Qt GUI编程的基础,使用信号与槽机制可以比较容易的将信号与响应代码关联起来。

第三章 Qt类库概述

  • Qt是一个用标准C++编写的跨平台开发类库,它对标准C++进行了扩展,引入了元对象系统,信号与槽,属性等特性,使应用程序的开发变得更高效。本章将介绍Qt的这些核心特点,对于理解和编写高效的Qt C++程序是大有帮助的。
  • 本章还介绍头文件中Qt的一些全局定义,包括数据类型,函数和宏等,介绍Qt的容器类及其响应迭代器的使用方法。这些全局定义和容器类在程序中经常用到,了解其原理便于理解后面遇到的一些实例程序。
  • Qt类库中大量的类是以模块形式分类组织的,包括基本模块和扩展模块等,本章对这些模块做一个总体的介绍。一个模块通常就是一个编程主题,例如数据库,图表,网格等。本书后面的章节一般是每章介绍一个编程主题。

3.1 Qt核心特点

3.1.1 概述

  • Qt本身并不是一种编程语言,它实质上是一个跨平台的C++开发类库,是用标准C++编写的类库,它为开发GUI应用程序和非GUI应用程序提供了各种类。

  • Qt对标准C++进行了扩展,引入了一些新的概念和功能,例如信号与槽,对象属性等。Qt的元对象编译器(Meta-Object Compiler, MOC)是一个预处理器,在源程序被编译前先将这些Qt特性的程序转换为标准C++兼容的形式,然后再由标准C++编译器进行编译。这就是为什么在使用信号与槽机制的类里,必须添加一个Q_OBJECT宏的原因,只有添加了这个宏,moc才能对类里的信号与槽的代码进行预处理。

  • Qt Core模块是Qt类库的核心,所有其他模块都依赖于此模块。Qt 为C++语言增加的特性就是在Qt Core模块里实现的,这些扩展特性由Qt的元对象系统实现,包括信号与槽机制,属性系统,动态类型转换等。

3.1.2 元对象系统

  • Qt的元对象系统(Meta-Object System)提供了对象之间通信的信号与槽机制,运行时类型信息和动态属性系统。

  • 元对象系统由以下三个基础组成

    • QObject类是所有使用元对象系统的类的基类。
    • 在一个类的private部分声明Q_OBJECT宏,使得类可以使用元对象的特性,例如动态属性,信号与槽。
    • MOC(元对象编译器)为每个QObject的子类提供必要的代码来实现元对象系统的特性。
  • 构建项目时,MOC工具读取C++源文件,当它发现类的定义里有Q_OBJECT宏时,它就会为这个类生成另外一个包含有元对象支持代码的C++源文件,这个生成的源文件连同类的实现文件一起被编译和链接。

  • 除了信号与槽机制外,元对象还提供如下一些功能

    • QOBject::metaObject()函数返回类关联的元对象,元对象类QMetaObject包含了访问对象的一些接口函数,例如QMetaObject::className()函数可在运行时返回类的名称字符串。
      1
      2
      QObject *obj = new QPushButton;
      obj->metaObject()->className(); // 返回"QPushButton
    • QMetaObject::newInstance()函数创建类的一个新的实例
    • QObject::inherits(const char* className)函数判断一个对象实例是否是名称为className的类或QObject的子类的实例。例如
      1
      2
      3
      4
      QTimer *timer = new QTimer; // QTimer是QObject的子类
      timer->inherits("QTimer"); // 返回true
      timer->inherits("QObject"); // 返回true
      timer->inherits("QAbstractButton"); // 返回false,不是QAbstractButton的子类
    • QObject::tr()和QObject::trUtf8()函数可翻译字符串,用于多语言界面设计。
    • QObject::setProperty()和QObject::property()函数用于通过属性名称动态设置和获取属性值。
  • 对于QObject及其子类,还可以使用qobject_cast()函数进行动态映射(dynamic cast)。

  • 使用动态投射,使得程序可以在运行时对不同的对象做不同的处理。

3.1.3 属性系统

  • Qt提供一个 Q_PROPERTY()宏可以定义属性,它也是基于元对象系统实现的。Qt的属性系统与C++编译器无关,可以用任何标准的C++编译器编译定义了属性的QtC++程序。
  • Q_PROPERTY宏定义一个返回值类型为type,名称为name的属性,用READ,WRITE关键字定义属性的读取,写入函数,还有其他的一些关键字定义属性的一些操作特性。属性的类型可以是QVariant支持的任何类型,也可以用户自定义类型。
  • Q_PROPERTY宏定义属性的一些主要关键字的意义如下
  • READ: 指定一个读取属性值的函数,没有MEMBER关键字时必须设置READ
  • WRITE: 指定一个设定属性值的函数,只读属性没有WRITE设置
  • MEMBER: 指定一个成员变量与属性关联,成为可读可写的属性,无需再设置READ和WRITE
  • RESET: 是可选的,用于指定一个设置属性缺省值的函数
  • NOTIFY: 是可选的,用于设置一个信号,当属性值变化时发射此信号
  • DESIGNABLE: 表示属性是否在Qt Designer里可见,缺省为true
  • CONSTANT: 表示属性值是一个常数,对于一个对象实例,READ指定的函数返回值是常数,但是每个实例的返回值可以不一样。具有CONSTANT关键字的属性不能有WRITE和NOTIFY关键字。
  • FINAL: 表示所定义的属性不能被子类重载

3.1.4 信号与槽

  • 信号与槽是Qt的一个核心特点,也是它区别于其他框架的重要特性。信号与槽是对象间进行通信的机制,也需要由Qt的元对象系统支持才能实现的。

  • Qt使用信号与槽的机制实现对象间通信,它隐藏了复杂的底层实现,完成信号与槽的关联后,发射信号时并不需要知道Qt是如何找到槽函数的。Qt的信号与槽机制与Delphi和C++ Builder的”事件–响应”比较类似,但是更加灵活。

  • 某些开发架构使用回调函数(callback)实现对象间通信。与回调函数相比,信号与槽的执行速度稍微慢一点,因为需要查找连接的对象和槽函数,但是这种差别在应用程序运行时是感觉不到的,而其提供的灵活性却比回调函数强很多。

  • 对信号与槽的特点和用法做一些补充

    1. connect()函数的不同参数形式
    • QObject::connect()函数有多重参数形式,一种参数形式的函数原型是
      1
      QMetaObject::Connection QObject::connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type = Qt::AutoConnection);
    • 使用这种参数形式的connect()进行信号与槽函数的连接时,一般句法如下
      1
      connect(sender, SIGNAL(signal()), receiver, SLOT(slot()));
    • 这里使用了宏SIGNAL()和SLOT()指定信号和槽函数,而且如果信号和槽函数带有参数,还需要注明参数类型,例如
      1
      connect(spinNum, SIGNAL(valueChanged(int)), this, SLOT(updateStatus(int)));
    • 另外一种参数形式的connect()函数的原型是:
      1
      QMetaObject::Connection QObject::connect(const QObject *sender, const QMetaMethod &signal, const QObject *receiver, const QMetaMethod &method, Qt::ConnectionType type = Qt::AutoConnection);
    • 对于具有默认参数的信号与槽(即信号名称是唯一的,没有参数不同而同名的两个信号),可以使用这种函数指针形式进行关联,例如
      1
      connect(lineEdit, &QLineEdit::textChanged, this, &widget::on_textChanged);
  • 不管是哪种参数形式的connect()函数,最后一个参数Qt::ConnectionType type,缺省值为Qt::AutoConnection。枚举类型Qt::ConnectionType表示了信号与槽之间的关联方式,有以下几种取值:

    • Qt::AutoConnection(缺省值): 如果信号的接收者与发射者在同一个线程,就使用Qt::DirectConnection方式;否则使用Qt::QueuedConnection方式,在信号发射时自动确定关联方式
    • Qt::DirectConnection: 信号被发射时槽函数立即执行,槽函数与信号在同一个线程
    • Qt::QueuedConnection: 在事件循环回到接收者线程后执行槽函数,槽函数与信号在不同的线程。
    • Qt::BlockingQueuedConnection: 与Qt::QueuedConnection相似,只是信号线程会阻塞直到槽函数执行完毕。当信号与槽函数在同一个线程时绝对不能使用这种方式,否则会造成死锁。
  1. 使用sender()获得信号发射者
    • 在槽函数里,使用QObject::sender()可以获取信号发射者的指针。如果知道信号发射者的类型,可以将指针投射为确定的类型,然后使用这个确定类的接口函数。
  2. 自定义信号及其使用
    • 在自己设计的类里也可以自定义信号,信号就是在类定义里声明的一个函数,但是这个函数无需实现,只需要发射(emit)
    • 例如,在下面的自定义类QPerson的signals部分定义一个信号ageChanged(int)
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      class QPerson : public QObject
      {
      Q_OBJECT
      private:
      int m_age = 10;
      public:
      void incAge();
      signals:
      void ageChanged(int value);
      }
  • 信号函数必须是无返回值的函数,但是可以有输入参数。信号函数无需实现,只需在某些条件下发射信号。例如,在incAge()函数中发射信号,其代码如下
    1
    2
    3
    4
    5
    void QPerson::incAge()
    {
    m_age++;
    emit ageChanged(m_age); // 发射信号
    }
  • 在incAge()函数里,当私有变量m_age变化后,发射信号ageChanged(int),表示年龄发生了变化。至于是否有此信号相关联的槽函数,信号发射者并不管。如果在使用QPerson类对象的程序中为此信号关联了槽函数,在incAge()函数里发射此信号时,就会执行相关联的槽函数。至于是否立即执行槽函数,发射信号的线程是否等待槽函数执行完之后再执行后面的代码,与connect()函数设置信号与槽关联时设置的连接类型以及信号与槽是否在同一个线程有关。

3.2 Qt全局定义

  • 头文件包含了Qt类库的一些全局定义,包括基本数据类型,函数和宏,一般的Qt类的头文件都会包含该文件,所以不用显示包含这个头文件也可以使用其中的定义。

3.2.1 数据类型定义

  • 为了确保在各个平台上各数据类型都有统一确定的长度,Qt为各种常见数据类型定义了类型符号,例如qint8就是signed char的类型定义,即 typedef signed char qint8;

3.2.2 函数

  • 头文件包含一些常用函数的定义,这些函数多以模板类型作为参数,返回相应的模板类型,模板类型可以用任何其他类型替换。若是以double或float类型作为参数的,一般有两个参数版本的额同名函数,例如qFuzzyIsNull(double d)和qFuzzyIsNull(float f)。
  • 还有一些基础的数学运算函数在头文件中定义,例如三角运算函数,弧度与角度之间的转换函数等。

3.2.3 宏定义

  • 头文件中定义了很多宏,以下是一些比较常用的

  • QT_VERSION

    • 这个宏展开为数值形式0xMMNNPP(MM = major, NN = minor, PP = patch)表示Qt编译器版本,例如Qt编译器版本为Qt 5.9.1,则QT_VERSION为0x050901。这个宏常用于条件编译设置,根据Qt版本不同,编译不同的代码段。
      1
      2
      3
      4
      5
      6
      #if QT_VERSION >= 0x040100
      QIcon icon = style()->standardIcon(QStyle::SP_TrashIcon);
      #else
      QPixmap pixmap = style()->standardPixmap(QStyle::SP_TrashIcon);
      QIcon icon(pixmap);
      #endif
  • QT_VERSION_CHECK

    • 这个宏展开为Qt版本号的一个整数表示,例如
      1
      2
      3
      4
      5
      #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
      #include <QtWidgets>
      #else
      #include <QtGui>
      #endif
  • QT_VERSION_STR

    • 这个宏展开为Qt版本号的字符串,例如 “5.9.0”
  • Q_BYTE_ORDER, Q_BIG_ENDIAN 和 Q_LITTLE_ENDIAN

    • Q_BYTE_ORDER 表示系统内存中数据的字节序,
    • Q_BIG_ENDIAN 表示大端字节序
    • Q_LITTLE_ENDIAN 表示小端字节序。
    • 在需要判断系统字节序时会用到,例如
      1
      2
      3
      #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
      ...
      #endif
  • Q_DECL_IMPORT, Q_DECL_EXPORT

    • 在使用或设计共享库时,用于导入或到处库的内容
  • Q_DECL_OVERRIDE

    • 在类定义中,用于重载一个虚函数,例如在某个类中重载虚函数paintEvent(),可以定义如下
      1
      void paintEvent(QPaintEvent*) Q_DECL_OVERRIDE;
    • 使用Q_DECL_OVERRIDE宏后,如果重载的虚函数没有进行任何重载操作,编译器将会报错。
  • Q_DECL_FINAL

    • 这个宏将一个虚函数定义为最终级别,不能再被重载,或定义一个类不能再被继承,实例如下
      1
      2
      3
      class QRect Q_DECL_FINAL {  // QRect不能再被继承
      // ...
      };
  • Q_UNUSED(name)

    • 这个宏用于在函数中定义不在函数体里使用的参数,示例如下
      1
      2
      3
      4
      5
      void MainWindow::on_imageSaved(int id, const QString &filename)
      {
      Q_UNUSED(id);
      LabInfo->setText("图片保存为: " + filename);
      }
    • 在这个函数里,id参数没有使用。如果不用Q_UNUSED(id)定义,编译器会出现参数未使用的警告。
  • foreach(variable, container)

    • foreach用于容器类的遍历,例如
      1
      2
      foreach (const QString &codecName, recorder->supportedAudioCodecs())
      ui->comboCodec->addItem(codecName);
  • forever

    • forever用于构造一个无限循环,例如
      1
      2
      3
      forever {
      ...
      }
  • qDebug(const char *message, …)

    • 在debugger窗体显示信息,如果编译器设置了 Qt_NO_DEBUG_OUTPUT,则不作任何输出,例如
      1
      qDebug("Item in list: %d", myList.size());
  • 类似的宏还有 qWarning, qCritical, qFatal, qInfo等,也是用于在debugger窗体显示信息。

3.3 容器类

3.3.1 容器类概述

  • Qt提供了多个基于模板的容器类,这些容器类可以用于存储指定类型的数据项,例如常用的字符串列表类QStringList就是从容器类QList继承的,实现对字符串列表的添加,存储,删除等操作。

  • Qt的容器壁标准模板库(STL)中的容器类更轻巧,安全和易于使用。这些容器类是隐式共享和可重入的,而且他们进行了速度和存储优化,因此可以减少可执行文件的大小。此外,它们还是线程安全的,也就是说它们作为只读容器时可以被多个线程访问

  • 容器类是基于模板的类,如常用的容器类QList,T是一个具体的类型,可以是int, float等简单的类型,也可以是QString, QDate等类,但是不能是QObject或任何其子类。T必须是一个可赋值的类型,即T必须提供一个缺省的构造函数,一个可复制构造函数和一个赋值运算符。

  • Qt的容器类分为顺序容器(sequential containers)和关联容器(associative containers)

  • 容器迭代类用于遍历容器里的数据项,有Java类型的迭代类和STL类型的迭代类。Java类型的迭代类易于使用,提供高级功能,而STL类型的迭代类效率更高一些。

  • Qt还提供了foreach宏用于遍历容器内的所有数据项。

3.3.2 顺序容器类

  • Qt的顺序容器类有 QList, QLinkedList, QVector, QStack和QQueue

  • QList

    • QList是最常用的容器类,虽然它是以数组列表(array-list)的形式实现的,但是在其前或后添加数据非常快。QList以下标索引的方式对数据项进行访问。
  • QLinkedList

    • QLinkedList是链式列表(linked-list),数据项不是用连续的内存存储的,它基于迭代器访问数据项,并且插入和删除数据项的操作时间相同。
      除了不提供基于下标索引的数据项访问外,QLinkedList的其他接口函数与QList基本相同。
  • QVector

    • QVector提供动态数组的功能,以下标索引访问数据。
    • QVector的函数接口与QList几乎完全相同,QVector的性能比QList更高,因为QVector的数据项是连续存储的。
  • QStack

    • QStack是提供类似于堆栈的后入先出(LIFO)操作的容器类,push()和pop()是主要的接口函数。
  • QQueue

    • QQueue是提供类似于队列先入先出(FIFO)操作的容器类。enqueue()和dequeue()是主要的操作函数

3.3.3 关联容器类

  • Qt还提供关联容器类 QMap, QMultiMap, QHash, QMultiHash和QSet

  • QMultiMap和QMultiHash支持一个键关联多个值,QHash和QMultiHash类使用散列(Hash)函数进行查找,查找速度较快

  • QSet

    • QSet是基于散列列表的集合模板类,它存储数据的顺序是不定的,查找值的速度非常快。QSet内部就是用QHash实现的。
    • 测试一个值是否包含于这个集合,用contains()函数
  • QMap

    • QMap<Key, T>提供一个字典(关联数组),一个键映射到一个值。QMap存储数据是按照键的顺序,如果不在乎存储顺序,使用QHash会更快
  • QMultiMap

    • QMultiMap是QMap的子类,是用于处理多值映射的便利类
  • QHash

    • QHash是基于散列表来实现字典功能的模板类,QHash<Key, T>存储的键值对具有非常快的查找速度。
  • QHash与QMap的功能和用法相似,区别在于以下几点

    • QHash比QMap的查找速度更快
    • 在QMap上遍历时,数据项是按照键排序的,而QHash的数据项是任意顺序的
    • QMap的键必须提供 “<” 运算符,QHash的键必须提供 “==” 运算符和一个名称为 qHash() 的全局散列函数
  • QMultiHash

    • QMultiHash是QHash的子类,是哟弄个与处理多值映射的便利类,其用法与QMultiMap类似

3.4 容器类的迭代

  • 迭代器(iterator)为访问容器类里的数据项提供了统一的方法,Qt有两种迭代器类: Java类型的迭代器和STL类型的迭代器
  • Java类型的迭代器更易于使用,且提供一些高级功能,而STL类型的迭代器效率更高。

3.4.1 Java类型迭代器

3.4.2 STL类型迭代器

  • STL迭代器与Qt和STL的原生算法兼容,并且进行了速度优化

  • 对于每一个容器类,都有两个STL类型迭代器:一个用于只读访问,一个用于读写访问。无需修改数据时一定使用只读迭代器,因为它们速度更快。

  • STL类型的迭代器是数组的指针,所以 “++” 运算符使迭代器指向下一个数据项, “*”运算符返回数据项内容。

  • 隐式共享(Implicit Sharing)是对象的管理方法,一个对象被隐式共享,只是传递该对象的一个指针给使用者,而不实际复制对象数据,只有在使用者修改数据时,才实质复制共享对象给使用者。

  • 对于STL类型的容器,隐式共享还涉及到另外一个问题,即当有一个迭代器在操作一个容器变量时,不要去复制这个容器变量。

3.4.3 foreach关键字

  • 如果只是想遍历容器中所有的项,可以使用foreach关键字。foreach是头文件中定义的一个宏。
  • foreach关键字遍历一个容器变量是创建了容器的一个副本,所以不能修改原来容器变量的数据项

3.5 Qt类库的模块

  • Qt类库里大量的类根据功能分为各种模块,这些模块又分为几大类
    • Qt基本模块(Qt Essentials): 提供了Qt在所有平台上的基本功能
    • Qt附加模块(Qt Add-Ons): 实现一些特定功能的提供附加价值的模块
    • 增值模块(Value-Add Modules): 单独发布的提供额外价值的模块或工具
    • 技术预览模块(Technology Preview Modules): 一些处于开发阶段,但是可以作为技术预览使用的模块
    • Qt工具(Qt Tools): 帮助应用程序开发的一些工具。

3.5.1 Qt基本模块

  • Qt基本模块是Qt在所有平台上的基本功能,它们在所有的开发平台和目标平台上都可用,在Qt5所有版本上是源代码和二进制兼容的。具体的基本模块如下
    • Qt Core: 其他模块都用到的核心非图形类
    • Qt GUI: 设计GUI界面的基础类,包括OpenGL
    • Qt Multimedia: 音频,视频,摄像头和广播功能的类
    • Qt Multimedia Widgets: 实现多媒体功能的界面组件类
    • Qt Network: 使网路编程更简单和轻便的类
    • Qt QML: 用于QML和JavaScript语言的类
    • Qt Quick: 用于构建具有定制用户界面的动态应用程序的声明框架
    • Qt Quick Controls: 创建桌面样式用户界面,基于Qt Quick的用户界面控件
    • Qt Quick Dialogs: 用于Qt Quick的系统对话框类型
    • Qt Quick Layouts: 用于Qt Quick 2界面元素的布局项
    • Qt SQL: 使用SQL用于数据库操作的类
    • Qt Test: 用于应用程序和库进行单元测试的类
    • Qt Widgets: 用于构建GUI界面的C++图形组件类

3.5.2 Qt附加模块

3.5.3 增值模块

3.5.4 技术预览模块

4.5.5 Qt 工具

  • Qt工具在所有支持的平台上都可以使用,用于帮助应用程序的开发和设计
    • Qt Designer: 用于扩展Qt Designer的类
    • Qt Help: 在应用程序中集成在线文档的类,实现类似于Qt Assistant的功能
    • Qt UI Tools: 操作Qt Designer生成的窗体的类

第四章 常用界面设计组件

第五章 Model/View结构

  • Model/View(模型/视图)结构是Qt中用界面组件显示与编辑数据结构的一种结构,视图(View)是显示和编辑数据的界面组件,模型(Model)是视图与原始数据之间的接口。Model/View结构的典型应用是在是数据库应用程序中。
  • 主要的视图组件有 QListVew, QTreeView和QTableView

第六章 对话框与多窗体设计

  • 在一个完整的应用程序设计中,不可避免地会涉及多个窗体,对话框的设计和调用,如何设计和调用这些对话框和窗体是搞清楚一个庞大的应用程序设计的基础。本章将介绍对话框和多窗体设计,调用方式,数据传递等问题,主要包括以下几点
    • Qt 提供的标准对话框的使用,例如打开文件对话框,选择颜色对话框,字体对话框,消息提示和确认选择对话框等
    • 自定义对话框的设计和调用,如何获取返回值,在对话框中如何操作主窗体等
    • 在一个应用程序中如何设计多种窗体,基于QDialog,QWidget和QMainWindow创建的窗体的调用方式有哪些,它们之间有什么区别
    • 如何创建一个在多页组件中管理的多窗体应用,类似于现在流行的多页浏览器的界面效果,子窗体如何与主窗体实现交互
    • 如何创建MDI(Multi-document interface)应用程序
    • 如何创建一个带有启动界面(Splash)和登录界面的窗体,如何保存和读取应用程序设置的参数。

第七章 文件系统和文件读写

  • 文件的读写是很多程序具有的功能,甚至某些应用程序就是围绕着某一种格式文件的处理而开发的,所以文件读写是应用程序开发的一个基本功能。
  • 本章介绍Qt中如何实现文本文件,二进制文件的读写,以及文件和目录的管理功能。

第八章 绘图

  • GUI用户界面的优势是通过可视化的界面元素为用户提供遍历的操作,界面上的按钮,编辑框等各种界面组件其实都是通过绘图而得到的。Qt的二维绘图基本功能是使用QPainter在绘图设备上绘图,绘图设备包括QWidget,QPixmap等,通过绘制一些基本的点,线,圆等基本形状组成自己需要的图形,得到的图形是不可交互操作的图形。
  • Qt还提供了Graphics View架构,使用GraphicsView, QGraphicsScene和各种QGraphicsItem类绘图,在一个场景中可以绘制大量图件,且每个图件是可选择,可交互的,如同矢量图编辑软件那样可以操作每个图件。Graphics View架构为用户绘制复杂的组件化图形提供了便利。

第九章 Qt Charts

  • Qt Charts是Qt提供的图表模块,在Qt 5.7以前只有商业版才有Qt Charts,但是从Qt 5.7开始,社区版本也包含了Qt Charts。Qt Charts可以很方便的绘制常见的折线图,柱状图,饼图等图表。

第十章 Data Visualization

  • Data Visualization是Qt提供的用于数据三维显示的模块。在Qt 5.7以前只有商业版才有Qt Visualization,但是从Qt 5.7开始,社区版本也包含了Qt Visualization
  • Data Visualization用于数据的三维显示,包括三维柱状图,三维空间散点,三维曲面等。

第十一章 数据库

  • Qt SQL模块提供数据库编程的支持,Qt支持多种常见的数据库,例如 MySQL, Oracle, MS SQL Server, SQlite等。Qt SQL模块包括多个类,可以实现数据库连接,SQL语句执行,数据获取与界面显示等功能,数据与界面之间使用Model/View架构,从而可以方便的实现数据的界面显示和操作。

第十二章 自定义插件和库

  • 当UI设计器提供的界面组件不满足实际需求时,可以从QWidget继承自定义界面组件。有两种方法使用自定义界面组件,一种是提升发(promotion);另一种是为UI设计器设计自定义界面组件的Widget插件,直接安装到UI设计器的组件面板里。

第十三章 多线程

  • Qt为多线程提供了完整的支持。QThread是线程类,是实现多线程操作的核心类,一般从QThread继承定义自己的线程类。线程之间的同步是其交互的主要问题,Qt提供了QMutex,QMutexLocker,QReadWriteLock,QwaitCondition,QSemaphore等多种类用于实现线程之间的同步。Qt还有Qt Concurrent模块,提供一些高级的API实现多线程编程而无需使用QMutex, QwaitCondition和QSemaphore等基础操作。使用Qt Concurrent实现的多线程程序可以自动根据处理器内核个数调整线程个数。
  • 本章主要介绍用QThread实现多线程编程的方法,以及用QMutex,QWaitCondition,QSemaphore等实现线程同步的方法。

13.1 QThread创建多线程程序

13.1.1 QThread类功能简介

  • QThread类提供不依赖于平台的管理线程的方法。一个QThread类的对象管理一个线程,一般从QThread继承一个自定义类,并重定义虚函数run(),在run()函数里实现线程需要完成的任务。

  • 将应用程序的线程称为主线程,额外创建的线程称为工作线程。一般在主线程里创建工作线程,并调用start()开始执行工作线程的任务。start()会在内部调用run()函数,进入工作线程的事件循环,在run()函数里调用exit()或quit()可以结束线程的事件循环,或者在主线程里调用terminate()强制结束线程。

  • QThread类的主要接口函数,信号和槽函数如下

    • 公共函数
      • bool isFinished(): 线程是否结束
      • bool isRunning(): 线程是否正在运行
      • Priority priority(): 返回线程的优先级
      • void setPriority(Priority priority): 设置线程的优先级
      • void exit(int returnCode = 0): 退出线程的事件循环,退出码为 returnCode,0表示成功退出,否则表示有错误
      • bool wait(unsigned long time): 阻止线程执行,直到线程结束(从run()函数返回),或等待时间超过time(毫秒)
    • 公共槽函数
      • void quit(): 退出线程的事件循环,并返回代码0,等效于exit(0)
      • void start(Priority priority): 内部调用run()开始执行线程,操作系统根据priority参数进行调度
      • void terminate(): 终止线程的运行,但不是立即结束线程,而是等待操作系统结束线程。使用terminate()之后应使用wait()
    • 信号
      • void finished(): 在线程就要结束时发射此信号
      • void started(): 在线程开始执行,run()函数被调用之前发射此信号
    • 静态公共成员
      • int idelThreadCount(): 返回系统上能够运行的线程的理想个数
      • void msleep(unsigned long msecs): 强制当前线程休眠msecs毫秒
      • void sleep(unsigned long secs): 强制当前线程休眠secs秒
      • void usleep(unsigned long usecs): 强制当前线程休眠usecs微妙
    • 保护函数
      • virtual void run(): start()调用run()函数开始线程任务的执行,所以在run()函数里实现线程的任务功能
      • int exec(): 由run()函数调用,进入此线程的事件循环,等待exit()退出。
  • QThread是QObject的子类,所以可以使用信号和槽机制。QThread自身定义了started()和finished()两个信号,started()信号在线程开始执行之前发射,也就是在run()函数被调用之前,finished()信号在线程就要结束时发射。

13.2 线程同步

13.2.1 线程同步的概念

  • 在多线程应用程序中,由于多个线程的存在,线程之间可能需要访问同一个变量,或一个线程需要等待另外一个线程完成某个操作后才产生相应的动作。

13.2.2 基于互斥量的线程同步

  • QMutex和QMutexLocker是基于互斥量的线程同步类,QMutex定义的实例是一个互斥量,QMutex主要提供3个函数

    • lock(): 锁定互斥量,如果另外一个线程锁定了这个互斥量,它将阻塞执行直到其他线程解锁这个互斥量。
    • unlock(): 解锁一个互斥量,需要与lock()配对使用
    • tryLock(): 试图锁定一个互斥量,如果成功锁定就返回true;如果其他线程已经锁定了这个互斥量,就返回false,但不阻塞程序执行。
  • 定义的互斥量mutex相当于一个标牌,可以这样来理解互斥量: 列车上的卫生间一次智能进一个人,当一个人尝试进入卫生间就是lock(),如果有人占用,它就只能等待;等里面的人出来,腾出了卫生间是unlock(),这个等待的人才可以进入并且锁住卫生间的门,就是lock(),使用完卫生间之后他再出来时就是unlock()

  • QMutex需要配对使用lock()和unlock()来实现代码段的保护,在一些逻辑复杂的代码段或可能发生一场的代码中,配对就可能出错。

  • QMutexLocker是另外一个简化了互斥量处理的类。QMutexLocker的构造函数接受一个互斥量作为参数并将其锁定,QMutexLocker的析构函数则将此互斥量解锁,所以在QMutexLocker实例变量的生存期内的代码段得到保护,自动进行互斥量的锁定和解锁。(与C++的自动锁原理一样,构造函数锁住互斥量,析构函数释放互斥量)

13.2.3 基于QReadWriteLock的线程同步

  • 使用互斥量时存在一个问题: 每次只能有一个线程获得互斥量的权限。如果在一个程序中有多个线程读取某个变量,使用互斥量时也需要排队。而实际上若只是读取一个变量,是可以让多个线程同时访问的,这样互斥量就会降低程序的性能。

  • Qt提供了QReadWriteLock类,它是基于读或写的模式进行代码段锁定的,在多个线程读写一个共享数据时,可以解决上面所说的互斥量存在的问题。

  • QReadWriteLock以读或写锁定的同步方法允许以读或写的方式保护一段代码,它可以允许多个线程以只读方式同步访问资源,但是只要有一个线程以写方式访问资源,其他线程必须等待直到写操作结束。

  • QReadWriteLock提供一下几个主要的函数

    • lockForRead(): 以只读方式锁定资源,如果有其他线程以写入方式锁定,这个函数会阻塞
    • lockForWrite(): 以写入方式锁定资源,如果本线程或其他线程以读或写模式锁定资源,这个函数就会阻塞。
    • unlock(): 解锁
    • tryLockForRead(): 是lockForRead()的非阻塞版本
    • tryLockForWrite(): 是lockForRead()的非阻塞版本
  • QReadLocker和QWriteLocker是QReadWriteLock的简便形式,如同QMutexLocker是QMutex的简便版本一样,无需与unlock()配对使用。使用QReadLocker和QWriterLocker。

13.2.4 基于QWaitCondition的线程同步

  • 在多线程的程序中,多个线程之间的同步实际上就是他们之间的协调问题。前面采用的互斥量和基于QReadWriteLock的方法都是对资源的锁定和解锁,避免同时访问资源时发生冲突。在一个线程解锁资源后,不能及时通知其他线程。

  • QWaitCondition提供了另外一种改进的线程同步方法,QWaitCondition与QMutex结合,可以使一个线程在满足一定条件时通知其他多个线程,使他们及时做出响应,这样比只使用互斥量效率更高一些。

  • QWaitCondition提供如下一些函数

    • wait(Qmutex *lockedMutex): 解锁互斥量lockedMutex,并阻塞等待唤醒条件,被唤醒后锁定lockedMutex并退出函数
    • wakeAll(): 唤醒所有处于等待状态的线程,线程唤醒的顺序不确定,由操作系统的调度策略决定
    • wakeOne(): 唤醒一个处于等待状态的线程,唤醒哪个线程不确定,由操作系统的调度策略决定
  • QWaitCondition一般用于 “生产者/消费者(producer/consumer)”模型中。

13.2.5 基于信号量的线程同步

  • 信号量(Semaphore)是另一种限制对共享资源进行访问的线程同步机制,它与互斥量(Mutex)相似,但是有区别。一个互斥量只能被锁定依次,而信号量可以多次使用。信号量通常用来保护一定数量的相同的资源,例如数据采集时的双缓冲区。

  • QSemaphore是实现信号量功能的类,它提供以下几个基本的函数

    • acquire(int n): 尝试获得n个资源。如果没有这么多资源,线程将阻塞直到有n个资源可用
    • release(int n): 释放n个资源,如果信号量的资源已全部可用之后再release(),就可以创建更多的资源,增加可用资源的个数
    • int available(): 返回当前信号量可用的资源个数,这个个数永远不可能为负数,如果为0,就说明当前没有资源可用
    • bool tryAcquire(int n = 1): 尝试获取n个资源,不成功时不阻塞线程。
  • 在定义QSemaphore的实例时,可以传递一个数值作为初始可用的资源个数。

第十四章 网络编程

  • Qt网络模块提供了用于编写TCP/IP客户端和服务端程序的各种类,例如用于TCP通信的QTcpSocket和QTcpServer,用于UDP通信的QudpSocket,还有用于实现HTTp,FTP等普通网络协议的高级类,例如QNetworkRequest,QNetworkReply和QNetworkAccessManager。

14.1 主机信息查询

14.1.1 QHostInfo 和 QNetworkInterface 类

  • 查询一个主机的MAC地址或IP地址是网络应用程序中经常用到的功能。

  • QHostInfo的静态函数 localHostName() 可获取本机的主机名,静态函数 fromName() 可以通过主机名获取IP地址,静态函数 lookupHost() 可以通过一个主机名,以异步方式查找这个主机的IP地址。

  • QNetworkInterface 可以获得运行应用程序的主机的所有IP地址和网络接口列表。静态函数 allInterfaces() 返回主机上所有的网络接口的列表,一个网络接口可能包括多个的IP地址,每个IP地址与掩码或广播地址关联。如果无需直到子网掩码和广播的IP地址,使用静态函数 allAddresses() 可以获得主机上的所有IP地址列表。

14.2 TCP通信

14.2.1 TCP通信概述

  • TCP(Transmission Control Protocol)是一种被大多数Internet网络协议(例如HTTP和FTP)用于数据传输的低级网络协议,它是可靠的,面向流,面向连接的传输协议,特别适合用于连续数据传输。

14.3 QUdpSocket 实现 UDP通信

14.3.1 UDP通信概述

  • UDP(User Datagram Protocol,用户数据包协议)是轻量的,不可靠的,面向数据报(datagram),无连接的协议,它可以用于对可靠性要求不高的场合。与TCP通信不同,两个程序之间进行UDP通信无需预先建立持久的socket连接,UDP每次发送数据报都需要指定目标地址和端口。
  • UDP消息传送有单播,广播,组播三种模式
    • 单播(unicast)模式: 一个UDP客户端发出的数据包只发送到另一个指定地址和端口的UDP客户端,是一对一的数据传输
    • 广播(broadcast)模式:一个UDP客户端发出的数据包,在同一个网络范围内其他所有的UDP客户端都可以收到。
    • 组播(multicast)模式: 也称多播。UDP客户端加入到另一个组播IP地址指定的多播组,成员向组播地址发送的数据包组内成员都可以接收到。
  • 使用广播和多播模式,UDP可以实现一些比较灵活的通信功能,而TCP通信只有单播模式,没有广播和多播模式。所以UDP通信虽然不能保证数据传输的准确性,但是具有灵活性,一般的即时通信软件都是基于UDP通信的。

14.4 基于HTTP协议的网络应用程序

14.4.1 实现高层网络操作的类

  • Qt网络模块提供一些类实现OSI七层网络模型中高层的网络协议,例如HTTP,FTP,SNMP等,这些类主要是QNetworkRequest, QNetworkReply和QNetowrkAccessManager

第十五章 多媒体

  • 多媒体功能指的主要是计算机的音频和视频的输入,输出,显示和播放等功能,Qt的多媒体模块为音频和视频播放,录音,摄像头拍照和录像等提供支持,甚至还提供数字收音机的支持。

15.1 Qt多媒体模块功能概述

  • 利用Qt多媒体模块提供的各种类,可以实现一般的音频,视频的输入和输出。

第十六章 应用程序设计辅助功能

  • 本章介绍Qt应用程序设计的一些辅助功能,包括设计多语言界面,使用样式表定制界面和组件的外观,使用QStyle设置界面外观,以及应用程序发布等。

简介

  • 关于windows下C++集成开发工具 Microsoft Visual Studio的学习笔记

项目和解决方案

  • 解决方案是一个容器,用于组织一个或多个相关的代码项目,例如,类库项目和对应的测试项目。
  • 在Visual Studio中,解决方案不是答案。解决方案仅仅是Visual Studio用来组织一个或多个相关项目的容器。打开某个解决方案时,Visual Studio会自动加载该解决方案包含的所有项目。

简介

  • 流媒体相关笔记

ZLMediaKit 关于流媒体的知识点

流媒体简介

  • 流媒体(streaming media)是指将一连串的媒体数据压缩后,经过网络分段发送数据,在网上即时传输影音以供观赏的一种技术与过程,此技术使得数据包得以像流水一样发送;如果不使用此技术,就必须在使用前下载整个媒体文件,这种对于实时性要求比较高的场景而言,显然是不现实的,所以流媒体技术为此孕育而生。
  • 传统的视频监控,IPTV,以及这几年兴起的视频直播,网络授课都属于流媒体的范畴,从广义上来讲,视频通话,视频会议也属于流媒体。

C++类的成员变量是在堆区还是在栈区

C++内存分配基础

  • 在理解C++类的成员变量存储位置之前,我们先要了解C++中的几种主要内存区域
    • 栈区(Stack): 栈区内存由编译器自动分配和释放,存储函数的局部变量,参数等。栈区内存具有生命周期短,分配效率高的特点
    • 堆区(Heap): 堆区内存由程序员手动分配和释放(使用new和delete)。堆区内存的生命周期由程序员控制,适合存储需要长时间存在的数据
    • 静态存储区(Static Storage): 该区域存储静态数据成员和全局变量,内存分配在程序开始时进行,直到程序结束时才释放
    • 代码区和常量区: 存储程序代码和常量数据

类的成员变量存储位置

  • 类的成员变量的存储位置取决于类的实例(对象)如何创建。主要有以下几种情况
  1. 栈上分配的对象

    • 当一个对象在栈上分配时,成员变量也存储在栈上
  2. 堆上分配的对象

    • 当使用new关键字动态分配一个对象时,对象和其成员变量会存储在堆上。
  3. 静态存储区的对象

    • 如果一个对象是全局变量或静态变量,那么它会被分配在静态存储区。
    • 这些对象的内存在程序开始时分配,并且在程序运行期间一直存在,直到程序结束时才会释放。因此,静态对象和全局对象的成员变量存储在静态存储区中。

C __BEGIN_DECLS 是什么

__BEGIN_DECLS__END_DECLS 是在C语言和C++代码混合时使用的宏。它们用于确保 C 头文件在被 C++ 编译器编译时能够正确处理 C 函数原型。

当在 C++ 环境中包含 C 头文件时,需要用 extern "C" 来告诉 C++ 编译器这些声明是 C 语言的,以便正确处理名字修饰(name mangling)。__BEGIN_DECLS__END_DECLS 宏正是为了简化这一过程而设计的。

1
2
3
4
5
6
7
#ifdef __cplusplus
# define __BEGIN_DECLS extern "C" {
# define __END_DECLS }
#else
# define __BEGIN_DECLS
# define __END_DECLS
#endif

这段代码的含义是:

  • 如果编译器是 C++ 编译器 (__cplusplus 被定义),则 __BEGIN_DECLS 被定义为 extern "C" {__END_DECLS 被定义为 }
  • 如果编译器是 C 编译器,则这两个宏都定义为空。

使用这些宏可以这样写一个头文件:

1
2
3
4
5
6
7
8
9
10
#ifndef MY_HEADER_H
#define MY_HEADER_H

__BEGIN_DECLS

void my_function();

__END_DECLS

#endif // MY_HEADER_H

当这个头文件在 C++ 代码中被包含时,my_function 的声明会被包含在 extern "C" 块中,从而避免了 C++ 名字修饰问题。在 C 代码中,宏会被定义为空,所以对代码没有影响。

简介

  • Linux系统下进程键通讯方式之共享内存,相关笔记

共享内存

  • 共享内存(shared memory)指在多处理器的计算机系统中,可以被不同中央处理器访问的大容量内存。由于多个CPU需要快速访问存储器,这样就要对存储器进行缓存。由于其他处理器可能也要访问,任一缓存数据更新后,共享内存就需要立即更新,否则不同处理器可能用到不同的数据。
  • 共享内存的类似方案有分布内存,分布共享内存,用以解决同类问题。
  • 共享内存区是可用IPC形式中最快的。一旦这样的内存区映射到共享它的进程的地址空间,这些进程间数据的传递就不再涉及内核。然而往该共享内存区存放消息或从中取走消息的进程间通常需要某种形式的同步。我们在第三部分讨论了各种形式的同步:互斥锁,条件变量,读写锁,记录锁,信号量。
  • 这里说的: 不再涉及内核的含义是: 进程不再通过执行任何进入内核的系统调用来彼此传递数据。显然,内核必须建立允许各个进程共享该内存区的内存映射关系,然后一直管理该内存区。

相关的方法

  • <sys/mman.h>头文件
    • mmap()函数

简介

  • 录制视频教程,std::vector相关笔记

vector

  • 看一下笔记,按照笔记复习。

  • 小结

    • std::vector 动态数组,动态增长的原理 1.5(2)倍增长,增长的流程,大概说一下。
    • size() 和 capacity() 的区别,
    • push_back 和 emplace_back() 的区别
    • 支持随机访问,常量时间复杂度,
    • 插入,删除操作是跟数据大小有关。
    • 下一个视频,复习一下 std::vector , std::list, std::deque, 主要是 std::vector 和 std::list的区别

list, array, deque, vector

  • list 相关的笔记

  • 小结

    • list 不能提供随机访问,也不能提供指针运算,只能通过 ++p 或 –p 来遍历list
    • 充分利用插入和删除常量时间复杂度的特性,两个list的合并 merge() , 或者是一个 list 的splice()
    • array 固定大小,在栈上分配内存,vector则是访问自由存储区,相对来说,效率会更高一些,
    • 缺点 swap() array是线性时间复杂度,vector是常量时间复杂度,
    • 与C风格的数组比较,优点就是封装了一些常用的方法,例如size(), empty()
    • deque
  • 下一步

    • 关联式容器: map, set, pair, multimap, multiset
    • 无序式关联容器: unordered_map, unordered_set,
    • 堆栈的一些概念,内存模型,类,虚函数表,this指针,成员函数的地址,怎么调用成员函数的。

map, set

  • 容器,分为序列容器和关联容器

    • 序列容器: vector, array, list, deque
    • 关联容器
      • 有序关联容器: map, set, multimap, multiset
      • 无序关联容器: unordered_map, unordered_set, unordered_multimap, unordered_multiset
  • 小结

    • 。。。
  • 下一步

    • cuda, cudnn, tensorrt
    • 深拷贝,
      • memcpy,strcpy,strlen()
    • 排序
      • std::sort() lambda()
      • algorithm
        • std::sort
        • std::merge
        • std::find_if
        • std::for_each
    • cuda
      • NVIDIA,
      • 异构
    • C++ 内存模型,堆栈一些概念

简介

  • 2022年,在江苏高重科技时,每周的工时填报,总结笔记

2022.06.09

  • 在2022年6月9日,我入职了江苏高重信息科技有限公司

  • 实习期两个月

  • 试用期六个月(其中包含了实习期的两个月)

  • 转正 2022年11月21日

20220609 - 20220630

  • OpenCV FFmpeg 对视频,图像的处理

    • OpenCV编程基础,常用编程技巧
    • FFmpeg编程基础
  • yolov3 目标检测

    • 检测模型工程应用
    • 深度学习理论基础

20220701 - 20220731

  • A311D 智能盒子的硬件推理加速功能适配

    • 人工智能,检测模型工程化
      • 前处理
      • 推理
      • 后处理
  • 遗留物检测

20220801 - 20220831

  • 密码云心 VideoProcess产品自启动服务,docker镜像制作
    • 项目部署
      • docker
      • shell
      • linux

20220901 - 20220930

  • 卓尔 动态人脸识别服务开发
    • 第一个C++服务器开发项目
    • 用到Fasis第三方库

20221001 - 20221030

  • 晶视1838 硬件 JPEG编码功能适配

    • 图像编解码编程基础
  • 卓尔动态人脸识别服务开发

20221101 - 20221130

  • 动态人脸识别服务开发

20221201 - 20221231

  • 机械臂主控系统后端服务器开发
    • mongoose 第三方工具使用
    • socket
    • Json
    • HTTP
    • WebSocket

简介

  • 2023年工作笔记

20230101 - 20230131

  • 机械臂主控系统后端服务器开发
    • restful 接口

20230201 - 20230230

  • 机械臂主控系统后端服务器开发
    • V1版本发布,测试,moveJoint moveLine功能

20230301 - 20230331

  • 03.01 - 03.13

    • 机械臂主控系统后端服务器开发
  • 03.13 - 03.18

    • V1版本重新打包,测试
    • 编程模块的接口实现,各自测试
      • Json数据格式应用
  • 03.20 - 03.26

    • 前后端联调,编程模块 单步调试,任务下发
  • 03.27 - 03.31

    • 解决任务下发bug
    • 整理V2版本代码,文档,程序打包,demo测试

20230401 - 20230408

  • 拖动示教功能,示教点保存

202304011 - 20230415

  • 遗留物检测 更新版

20230417 - 20230421

  • 基于位置的拖动示教
  • 基于力矩的拖动示教

20230424 - 20230428

  • rockchip平台适配

20230501 - 20230507

  • 端午节放假

20230509 - 20230513

  • rk平台开发
    • 边缘计算产品 底层服务器开发

20230514 - 20230528

  • rk平台,工地盒子,业务流程开发 管理界面开发

20230529 - 20230604

  • rk平台,管理节点,基础功能开发
    • 用户管理
    • 算法管理
    • 任务管理
    • 告警信息管理
    • 增删改查

20230605 - 20230609

  • rk平台,完成算力节点,业务发开

    • 安全帽检测
    • 反光衣检测
    • 烟火检测
    • 区域入侵
  • 完成图片和结构化数据传输

    • 共享内存方式,传输图片

20230612 - 20230616

  • rk平台,图片流服务,管理节点集成工作
  • 基本实现了单个任务,单个检测的管理
  • 解决机械臂使能时间长问题

20230619 - 20230625

  • 后端各模块联调,保证各模块对外接口可用,前后端联调
  • arm平台编译

20230626 - 20230630

  • rk平台的补充和优化
  • 对vca的交互由命令式改为网络请求式
  • 对外提供任务参数,灵敏度,告警间隔,区域
  • 优化任务启动,停止任务
  • 告警模块的优化

20230703 - 20230709

  1. 优化大屏视频播放功能,实现多任务功能
  2. 实现原图保存功能:保存图片到磁盘;实现最大告警数量限制:防止占满磁盘容量

20230710 - 20230716

  1. RK平台工地项目部署,测试,现场视频取回
  2. 协作机械臂SDK修复,优化;辅助算法组手动完成手眼标定测试

20230717 - 20230723

  1. 机械臂:增加上电复位功能,拖动示教bug排查
  2. rk平台:增加盒子信息页面和系统配置页面
  3. 卓尔:车牌识别和遗留物检测模型测试和部署

20230724 - 20230728

  1. rk平台:增加说明文档接口,事件推送接口
  2. 机械臂:解决相机标定,机械臂坐标系不统一问题,标定流程打通

20230731 - 20230804

  • VCR:

    1. 电动吸盘基本功能调试完成
    2. 正在开发电动吸盘服务
  • RK:

    1. 增加任务自启动
    2. 增加设备ID

20230807 - 20230811

  • VCR:

    1. 机械臂控制,电动吸盘控制的连接和测试,前端–后端–设备端技术路线打通
    2. 后两周:
      1. 接入相机,通过SDK拉取视频流,解码成一张张图片,通过模型获取轮廓信息和旋转角度,再通过深度信息获取3D姿态
      2. 接入传送带
  • 周一

    • VCR
      • vca增加vcr目录
      • 增加base server
    • RK
      • 制作rk镜像
  • 周二

    • VCR
      • server工具改成Comm类
      • 测试控制电动吸盘
    • RK
      • 增加HTTPS请求
      • 修复相机编辑bug
  • 周三

    • VCR
      • 增加电动吸盘的控制
      • 增加机械臂的控制
  • 周四

    • VCR
      • 优化电动吸盘和机械臂请求
  • 周五

    • VCR
      • 增加图漾SDK,在unit-test实现获取图片功能
  • VCR

    • 开发VCR项目,增加电动吸盘控制,增加机械臂控制,与后端联调机械臂和电动吸盘的连接和控制测试
  • RK

    • 事件推送支持HTTPS协议

20230814 - 20230818

  • VCR:

    • 图漾相机拉流,获取图片
    • yolov5s_6_OBB模型的工程化,输入图片,输出目标的轮廓数据
  • 周一

    • VCR
      • 图漾相机在VideoProcess项目下的调试
  • 周二

    • VCR
      • 增加图漾相机设备控制模块,可以拉取图片
      • 增加检测器模块,可以检测目标,输出结构化数据
      • 优化电动吸盘的控制
  • 周三

    • VCR
      • 重构设备管理层
      • 优化接口文档
  • 周四

    • RK
      • 修复检测框错位问题
      • 增加相机地址测试功能
  • 周五

    • RK
      • 修复重复告警问题
      • 修复任务删除bug
  • VCR

    • 增加图漾相机控制模块,增加检测器模块,能够拉取图片,检测,返回结构化数据
  • RK

    • 修复检测框错位问题
    • 增加相机地址测试功能
    • 完成rk1126操作文档-简版

20230821 - 20230825

  • VCR

    • 位姿检测算法工程化
  • 周一

    • 检测目标的点云 : yolov5_obb算法检测出来的目标,结合相机的深度图,输出这个目标的点云数据
  • VCR

    • 点云计算算法工程化
    • 坐标转换算法工程化
    • 结果: 能够输出正确的目标中心点位置和姿态数据
  • RK

    • 完成第一版操作手册

20230828 - 20230901

  • VCR

    • 实现无序抓取
  • 08.28

    • 测试算法输出的目标点是否可用
  • 08.29

    • 优化点云处理算法
  • 08.30

    • 增加多目标检测,结构化数据输出
  • 08.31

    • 解决多目标检测bug
    • 完成第一次无序抓取试验
  • 09.01

    • 优化错误处理
    • 优化检测器模块,修复kdtree计算bug
  • VCR

    • 实现平面下多目标的无序抓取

20230904 - 20230908

  • VCR
    • 优化位姿检测
    • 拆垛 + 定点放置 流程!
    • 末端工具增加检测工件是否吸取接口
    • 调试最新版机械臂主控系统SDK,可进行速度控制,正解, 逆解

20230911 - 20230915

  • VCR

    • 无序抓取优化版本
      • 可调节速度
      • 高抓取率
      • 连续抓取
  • 09.11

    • 机械臂接口异步封装成同步
    • 末端工具检测是否抓取到工件 第一次测试成功
    • 解决机械臂控制问题,原因是使用的是debug版本,需要使用release版本
    • 优化检测区域,增大检测区域,不再检测区域,也会保存图片,便于调试
    • 速度可调节,在参数中设置,建议关节空间移动为20-30,笛卡尔空间直线移动为0.2-0.3
  • 09.12

    • 机械臂测试,优化python测试代码,调试了机械臂的速度:机械臂的速度不能是全局统一的,每个步骤的速度都要定制
    • 安装了ubuntu22.04系统
    • 梳理任务清单:
      • vcr后端服务器,处理api模块重构,使用查表方式
      • 相机模块,添加相机曝光参数
      • 末端工具,电动吸盘判断是否抓到工件接口bug修复
      • 机械臂模块,统一接口的处理,统一请求的数据格式
  • 09.13

    • 联合python后端,一起测试,调整无序抓取业务流程
      • 编译离线的机械臂SDK,自己测自己的。
      • 北京的支持脱离机械臂调试
    • 同一个目标,同一个位置,多次抓取测试,定位算法检测精度问题
      • 点云转换时出现了误差,手动调整标定数据
  • 09.14

    • 优化Status类,增加JSON数据
    • 目标位姿增加偏移量算法
  • 09.15

    • 优化服务器层面,由同步改为异步,为每一个请求申请一个线程 [完成]
    • 优化机械臂控制层面,对机械臂的控制指令加上原子锁 [完成]
    • 修改代码,增加相对位姿和绝对位姿 [完成]
    • 欧拉角和轴角的相互转化
    • rk平台视频流重连bug修复

20230918 - 20230922

  • 09.18

    • 无序抓取步骤测试 [完成]
    • 输出数据由 小数 转为 整数
  • 09.19

    • 姿态控制修复
      • 欧拉角转为旋转矩阵,轴角转为旋转矩阵,两个旋转矩阵做运算,最后再转为欧拉角或者轴角 [完成]
    • 输出格式
      • 姿态对外统一单位为 角度,并且取整数 [完成]
      • 小数点统一乘以 1000000 取整数 [完成]
    • 拖动示教接口调试
      • 金属板质量 : 0.637 kg
      • 电动吸盘质量 : 1.405 kg
      • 电动吸盘质心 : -0.035310, -0.000020, 0.001640
    • 获取当前位置和姿态
  • 09.20

    • 输出格式 [完成]
      • 姿态
      • 位置 输出米
      • 关节角 输出 角度
    • 检测器输出的结构体
      • 长宽高
      • 位置 [完成]
      • 刻度值(由轴角转换得到的欧拉角) [完成]
  • 09.21

    • 检测器输出的结构体 [完成]
      • 长宽高
  • 09.22

    • 传送带 [完成]
    • rk平台远程安装 [完成]
    • 机械臂调试
    • yolov8 掩码 模型
  • 下周工作

    • rk 优化,推送视频流 rtmp
    • 机械臂 输出位姿数据优化
      • 滤波,
      • 多次计算,选在指定区间的数据
    • yolov8 掩码 点云

20230925 - 20230928

  • 机械臂 姿态 滤波

    • 解决输出姿态数据跳跃问题,实现稳定输出和稳定控制
  • 北京 机械臂本体控制,输入多个中间点,连续运动,实现连续规划

    • 是否支持,用于避障
    • 怎么使用
  • 无锡,作为展示基地

  • 12月底,实现两个demo

    • 无序抓取 + 传送带
    • 臂上相机 + 打磨
  • 09.25

    • 姿态数据滤波
      • 范围 : 现在 -180 到 180 , 限制范围 0 - 360
      • 数据 : 稳定,不再跳变
      • rx 设置0,ry设置180 可用,但是使3D退变成2D
  • 09.26

    • 姿态控制的两个问题
      • 硬件控制层:输出的姿态数据不稳定,表示含义不够清晰,或者表达的不够清晰
      • 业务应用层:对当前输出的姿态数据,不知道怎么应用,以最小的代价旋转到目的姿态
    • 试验公式
    • 找出rx , ry 正负数的规律,我认为是rx,ry影响了最终旋转方向
    • 点云计算,X轴法向量处理问题 [完成]
      • VCR版本 vcr_release/20230926
    • 3D 模型适配
  • 09.27

    • 3D 模型适配
      • YOLOv8-Infer boxs.onnx
      • VideoProcess/test/old/test.cpp:: test_get_mask
      • 输入检测图,输出检测信息
        • 目标的最小外接矩形
        • 目标的掩码图
  • 09.28

    • 3D 模型适配
      • 平面下抓取 [完成]
      • 倾斜物体,等待变换算法更新 [完成]
        • 使用之前的坐标变换算法
    • 待解决的问题
      • Z轴方向量正负号过滤,防止Z轴方向朝上
      • 位置有误差,测试和微调
      • 姿态测试,尽量趋近于理想情况,平行于物体表面
      • 输出轮廓信息
    • 设备的启动和停止服务优化
      • 检测器 [完成]
      • 图漾相机
      • 电动吸盘

20230929 - 20231006

  • 国庆 + 中秋 假期

20231007 - 20231013

  • VCR项目 研发环境 到 工作环境

  • 3D 倾斜物体的抓取和放置

  • 检测图像,目标三维信息上传,支持前端仿真 [完成]

  • 传送带,接口和速度参数 [完成]

  • RK平台,视频流播放

  • 10.07

    • 设备的启动和停止服务优化
      • 检测器 [完成]
      • 图漾相机 [完成]
      • 电动吸盘 [完成]
      • 机械臂 [待完善]
    • 检测图像,目标三维信息上传
    • 配置文件[完成]
      • 使用JSON
      • YAML 需要用到yaml-cpp第三方库,这个库需要编译静态库,所以使用JSON
      • 模型的加载 升级为由配置文件控制
    • RK
      • 收到的两个盒子: 升级固件,更新docker [完成]
  • 10.08

    • 检测图像,目标三维信息上传 [完成]
    • 传送带 配置信息由配置文件获取 [完成]
  • 10.09

    • 请求分发结构优化,增强可扩展性 [完成]
    • 3D 倾斜物体的抓取和放置 [ing]
      • 检测器层优化,能够正常抓取,位置与中心点有偏差,需要查看点云数据,分析问题
  • 10.10

    • YoloV8 检测模型 优化
      • 解决Z轴法向量正负号问题 [完成]
      • 解决中心点位置误差问题 [完成]
        • 法向量,相机坐标系下的中心点坐标: 误差看着不大
        • 坐标转换
    • 实际抓取,放置测试
  • 10.11

    • 实际抓取,放置测试 [完成]
      • python测试代码
      • 空间中两点的直线 [业务实现]
    • 姿态问题
  • 10.12

    • 姿态问题 [完成]
      • 优化坐标转换算法
    • 支持后端业务开发
    • 垂直于物体表面上方的某一点
  • 10.13

    • VCR测试 [完成]
    • 只解决能力问题(添加接口),精度问题(协作算法)
    • 检测精度 [ing]
      • 相机坐标系下,检测出来的盒子高度为 7cm
    • 增加真实世界的长度和宽度,坐标系偏移量
  • 小结

    • 解决3D物体位姿抓取问题
      • 分析并解决Z轴法向量正负号问题,这可能导致机械臂从下方抓取物体
      • 优化坐标转换算法,解决抓取姿态问题
    • 传送带功能完成,接口文档发给后端
    • 上传目标三维信息,真实宽度和高度,坐标系偏移量,为划区域回显提供数据
    • 优化检测精度
      • 试验和分析导致检测出现误差的原因,和算法组沟通优化检测精度

20231016 - 20231022

  • RK平台视频流转发功能

  • 10.16

    • 安全帽,反光衣算法延迟问题测试 [完成]
      • 不是算法的问题
    • NVR 接口接入
      • 熟悉了nvr服务的使用
  • 10.17

    • RK平台增加rtmp流转发功能
      • 完成NVR客户端 [完成]
      • nvr配置文件 读取 [完成]
        • 路径:/data/static/config/nvr_config.json
      • 修改相机数据库表[完成]
      • x86开发环境下功能测试 [完成]
      • rk运行环境下部署 [完成]
        • 启动 MediaServer
        • 启动 nvr
        • 启动 vca
        • 启动 mnc
      • rk镜像打包 [完成]
  • 10.18

    • 辅助算法组标定板标定 [完成]
    • rk平台优化
      • 前端界面的走势图
        • 按周,按月展示,
        • 按检测类型,展示多类检测结果总数
      • 算法界面
        • 型号,算力平台修改
      • 盒子界面
        • 子网掩码添加
      • 系统配置
        • 按照时间自动清理
      • nvr更新
        • 对vca使用MediaServer输出的rtsp流
        • 对外输出rtmp流地址
  • 10.19

    • rk平台优化
      • 前端界面的走势图[完成]
        • 按周,按月展示,
        • 按检测类型,展示多类检测结果总数
      • nvr更新 [完成]
        • 对vca使用MediaServer输出的rtsp流
        • 对外输出rtmp流地址
      • 算法界面 [完成]
        • 型号,算力平台修改
      • 盒子界面 [完成]
        • 子网掩码添加
      • 系统配置 [完成]
        • 按照时间自动清理
          • autoDeleteEventTimeThreshold
    • hugo 网络博客第一次搭建 [完成]
  • 10.20

    • 自动标定算法测试 [完成]
      • 与手动标定误差不大,可以使用
    • rk平台优化
      • 代码优化 [完成]
        • 编译告警
      • 任务切换卡顿
      • 前端联调
    • 相机曝光参数api
  • 小结

    • RK平台
      • 接入nvr服务,添加rtmp流格式转发
      • 走势图接口优化,自动清理策略增加按时间清理策略
    • VCR项目
      • 自动标定算法结果测试
      • 自动标定结果测试和优化

20231023 - 20231029

  • RK前端联调,docker镜像制作

  • VCR

    • 精度问题
    • 自动标定算法工程化
  • 10.23

    • RK
      • 前端联调
      • docker镜像制作
    • VCR
      • 算法精度,增加位置补偿 [完成]
      • 测试设备接口,交给后端测试 [完成]
  • 10.24

    • RK
      • docker 镜像制作
    • VCR
      • 新模型检测精度测试
      • 臂上相机运行环境配置
        • 192.169.0.162: user/123456
        • 搞清楚底层运行环境,总线协议
      • 自动标定算法工程化
      • 模板匹配模型
  • 10.25

    • 十公斤机械臂标定环境搭建
    • 自动标定算法集成
  • 10.26

    • 十公斤机械臂标定 [完成]
      • 主控系统前端控制
      • 标定
    • 英伟达驱动安装 [完成]
    • RK平台视频推流服务 [ing]
  • 10.27

    • 10kg机械臂环境搭建
      • 主控系统 [完成]
      • 视觉控制系统 [完成]
      • 手眼标定 [完成]
      • 检测算法 [完成]
      • 相机设备
      • 末端工具-夹爪
    • RK平台视频推流服务
    • 抓取运动物体
      • 检测一次,耗时太久
        • 添加标志位,默认传输图像,如果关闭,就不传输,节省计算时间 [后续在加]
      • 优化检测器模块
        • 增加图片获取时间戳 [完成]
        • 算法检测耗时
          • 注释掉VCR_DEBUG,编译release版本,检测一次,平均0.7秒
  • 小结

    • VCR
      • 和算法组协调,增加位置补偿,缩小抓取点误差
      • 10kg机械臂环境搭建,通过自动标定算法完成标定
      • 检测接口,增加图片时间戳,便于计算时间误差;注释掉调试代码,编译release版本,经过测试,检测一次,耗时0.7秒左右
      • 正在做自动算法工程化,加入到VCR项目,动态物体抓取

20231030 - 20231105

  • VCR

    • base64图像编码 – GPU版本
    • 电动夹爪
    • 自动标定算法
    • 运动目标抓取
  • RK

    • 新版NVR
    • 点播相机
    • frp服务
  • 10.30

    • 提供动态检测接口
      • 获取目标位姿 [完成]
      • 时间戳 [完成]
      • 瞬时速度 [完成]
      • 隐含的速度检测参数
    • 测试
      • 检测的速度波动较大,0.02 到 1.10
    • 目标:
      • 保证检测的速度尽量准确,稳定
      • 其次,才是单元测试
  • 10.31

    • 优化速度检测算法 [完成]
      • 多检测几次
      • 检测时间可配置
      • 是否检测到目标的判断 [可选]
    • 增加检测器配置文件,用于外部控制是否保存文件,便于调试和测试 [完成]
    • 测试算法耗时
    • 优化单元测试逻辑
  • 11.01

    • 新版本机械臂服务 [完成]
      • boost 库使用
    • 机械臂移动到目标位置业务逻辑优化 [待试验]
      • 如果moveLine失败,则调用逆解,获取目标位姿的关节角,使用moveJoint
      • 最后,再次调用moveLine,调整位置,以达到目标位置
    • 测试算法耗时 [完成]
    • 优化单元测试业务逻辑
      • 固定抓取点
  • 11.02

    • 优化速度检测算法 [完成]
      • 增加了检测区域参数
    • 优化抓取业务逻辑:固定点抓取 [完成]
  • 11.03

    • 动态抓取测试demo [完成]
    • 标定:[完成]
      • 数据采集
    • 机械臂本体:
      • 机械臂最大速度设置
      • MoveTo接口增加异步接口 [完成]
      • 任务相关接口封装 [完成]
        • 暂停任务
        • 继续任务
        • 清除所有任务
        • 检查是否有任务在运行
    • 图漾相机 [完成]
      • 查找获取时间的接口
    • 动态检测接口:
      • 增加物体运动方向 [完成]
        • 向哪一个方向运动
          • 象限
      • 增加检测间隔和次数 [完成]
  • 小结

    • VCR(协作机器人视觉控制系统)
      • 新增动态目标检测接口,可设置检测区域,检测次数,检测间隔,可获取目标的运动速度,运动方向,用于上层业务开发
      • 编写动态目标抓取测试用例,用于测试动态目标检测接口,可以比较顺利的抓取动态目标,保证接口可正确工作,后面提供给上层作业务开发
      • 机械臂服务适配最新版本代码,增加异步控制接口,清空任务接口,查询是否有任务在运行接口,用于上层业务开发
      • 协助算法组测试标定精度,采集位姿数据用于标定结果的补偿矩阵计算并测试,误差在五毫米左右

20231106 - 20231113

  • VCR

    • 速度检测算法测试
    • 增加自动标定功能
      • 星源哲相机SDK
      • 自动标定算法测试
      • 流程设计
      • 结果测试
      • 自动标定算法工程化
  • NodeMCU

    • 点灯
    • 连接WiFi
  • 11.06

    • VCR
      • 速度检测算法测试 [完成]
    • NodeMCU
      • 点灯 [完成]
  • 11.07

    • VCR
      • 机械臂抓取延迟测试 [完成]
      • 3kg机械臂标定 [完成]
    • NodeMCU
      • 连接WiFi [完成]
    • 10kg机械臂任务
      • 臂上相机 星猿哲相机SDK适配
        • RGB图
        • 深度图
        • 点云
      • 标定
      • 测试标定结果
  • 11.08

    • 10kg机械臂 臂上相机标定
      • 获取标定结果 [完成]
      • 标定结果测试
        • vcr适配星猿哲相机
  • 11.09

    • 标定结果测试
      • 末端工具标定
        • 末端工具标定接口使用
          • 新版本机械臂 [完成]
          • 末端工具标定新接口使用 [完成]
          • 拖动示教模式 测试 [完成]
      • 相对于机械臂末端的位姿数据变换到机械臂基底坐标系的位姿
        • 机械臂末端位姿–》矩阵–》矩阵的逆
        • 目标的位姿–》矩阵 –》左乘机械臂末端矩阵的逆
        • moveRel接口 [完成]
          • 在指定空间(关节/笛卡尔基座/笛卡尔工具中心点)中做指定的相对运动。运动轨迹为对应空间中的直线。
    • 标定结果测试的结果 [完成]
      • x轴,z轴误差 1cm以内
      • y轴误差 2.5cm左右
  • 11.10

    • VCR
      • 主线任务: 标定算法的功能集成到VCR基础服务
    • 星猿哲相机适配
      • RGB图,目标检测
      • 目标点云获取
      • 目标点云处理,获取目标位姿
    • 末端工具适配
      • 气泵工具
      • 末端夹爪
    • 模板匹配算法适配
    • 项目名称更正
      • vcr : version control robot
  • 小结

    • VCR
      • 速度检测算法解决延迟问题
      • 10kg机械臂,眼在手上的手眼标定,标定结果的测试,误差为1.1厘米
      • 自动标定算法集成到VCR项目中,
      • 配合后端,测试VCR已完成的功能

20231113 - 20231120

  • 11.13

    • 动态物体速度检测优化。高速情况,尽量1-2秒内测速完成 [完成]
      • 传送带速度: 11 cm/s
    • 修复多任务检测时,服务崩溃的问题 [完成]
  • 11.14

    • 整合所有已经完成的功能到测试机 [完成]
    • 检测,抓取,放置整个过程3-5秒内完成,成功率不少于90%. [ing]
    • 联合算法组验证标定数据准确性 [完成]
    • 末端旋转速度验证 [完成]
  • 11.15

    • 检测,抓取,放置整个过程3-5秒内完成,成功率不少于90%. [ing]
    • 解决vcr稳定性问题 [完成]
      • 段错误
      • 崩溃
      • gpu泄露
    • 臂上相机标定
  • 11.16

    • 更新测速算法
  • 11.17

    • 增加动态物体测速算法

20231120 - 20231127

  • 11.20

    • 新增动态物体测速算法 [完成]
      • 梳理代码逻辑:选取X最大的目标为同一目标,增加检测区域
      • 增加标准差和速度差阈值
  • 11.21

    • 移植机械臂控制模块到基础组件 [ing]
    • 准备rk盒子 [完成]
  • 11.22

    • 移植机械臂控制模块到基础组件
    • rk盒子增加视频点播功能,启用新版本的nvr [完成]
  • 11.23

    • 移植机械臂控制模块到基础组件
    • rk盒子与前端联调,解决稳定性问题
  • 11.24

    • 完成机械臂控制模块移植工作
    • rk平台完成管理平台增删改查接口
    • 辅助算法组完成10kg机械臂相机标定
  • 小结

    • 新增动态目标测速算法
    • rk平台适配新版本NVR,增加视频点播功能,增加管理平台的增删改查接口
    • 辅助算法组完成10kg机械臂眼在手上的相机标定
    • 机械臂控制模块移植剩余部分功能未实现,下周继续完成

20231127 - 20231203

  • 11.27

    • 机械臂控制模块移植 [完成]
  • 11.28

    • 在测试环境验证新的动态物品抓取算法和流程。(眼在手外) [ing]
      • 相机模块 [ok]
      • 检测器模块
      • 机械臂模块 [ok]
      • 电动吸盘模块
  • 11.29

    • 在测试环境验证新的动态物品抓取算法和流程。(眼在手外) [ing]
      • 相机模块 [ok]
      • 检测器模块 [ok]
      • 机械臂模块 [ok]
      • 电动吸盘模块
  • 11.30

    • 在测试环境验证新的动态物品抓取算法和流程。(眼在手外) [ing]
      • 相机模块 [ok]
      • 检测器模块 [ok]
      • 机械臂模块 [ok]
      • 电动吸盘模块
      • 解耦
        • 获取目标位姿流程
          • 目标池化
        • 决策算法流程
        • 实际抓取流程
      • 控制流程测试
        • 静态的平面抓取
        • 静态的斜面抓取
        • 动态的平面抓取
  • 12.01

    • 在测试环境验证新的动态物品抓取算法和流程。(眼在手外) [ing]
      • 相机模块 [ok]
      • 检测器模块 [ok]
      • 机械臂模块 [ok]
      • 电动吸盘模块
      • 解耦
        • 获取目标位姿流程
          • 目标池化
        • 决策算法流程
        • 实际抓取流程
      • 控制流程测试
        • 静态的平面抓取
        • 静态的斜面抓取
        • 动态的平面抓取

20231204 - 20231210

  • 12.04

    • 多个静态目标的抓取 [ok]
    • rk平台
      • 不稳定bug
      • ip修改功能增加
      • 任务启动等待时间太长 [ok]
        • 改为异步的
    • 动态目标的抓取
    • glog
      • 限制日志文件大小 [ok]
  • 12.05

    • 动态目标抓取
  • 12.06

    • 请假
  • 12.07

    • 动态抓取流程优化
    • rk平台
      • ip修改 [ok]
  • 12.08

    • 动态抓取流程
    • 机械臂版本SDK集成

20231211 - 20231217

  • 12.11

    • vcr
      • 接入吸盘 [ok]
    • rk
      • 优化ip配置接口 [ok]
      • 与前端联调 [ok]
  • 12.12

    • vcr
      • 解决姿态旋转问题
        • 静态拍摄几组不同姿态的目标,做测试
      • python版本
        • 解决相对移动问题,增加相对运动接口 [ok]
      • 眼在臂上的抓取 [ok]
    • rk
      • 测试新功能,制作docker镜像
      • 发货 5.63 [ok]
  • 12.13

    • rk
      • 掩码解析 [pl]
      • vca问题查找 [ok]
    • vcr
      • 末端姿态最小代价 [ok]
  • 12.14

    • vcr
      • 优化速度检测算法
        • 误差在2mm/s以内
        • master分支
          • 参数化
    • rk
      • 制作镜像
  • 12.15

    • 第一版本vcr封版
    • 第二版本vcr
      • 网络工具使用 httplib
        • 试验JSON数据和图片的传输

20231218-20231224

  • 12.18

    • vcr_0.5 [ing]
      • 设备和算法模块 12.21完成
    • rk
      • 任务配置增加音柱,系统平台增加音箱配置 12.23完成
  • 12.19

    • vcr_0.5 [ing]
      • 设备和算法模块 12.21完成
        • 算法模块 [ing]
          • 作业算法
            • 眼在臂外
            • 眼在臂上
            • 眼在臂上的打磨
          • 视觉算法 [ok]
            • YOLOV5OBB
            • YOLOV8BOX
  • 12.20

    • vcr_0.5 [ing]
      • 设备和算法模块 12.21完成
        • 算法模块 [defer]
          • 作业算法
            • 眼在臂外
            • 眼在臂上
            • 眼在臂上的打磨
          • 视觉算法 [ok]
            • YOLOV5OBB
            • YOLOV8BOX
        • 设备模块 [ing]
          • 机械臂 [ok]
          • 相机
          • 传送带
          • 末端工具
  • 12.21

    • vcr_0.5 [ing]
      • 设备和算法模块 12.21完成
        • 算法模块 [defer]
          • 作业算法
            • 眼在臂外
            • 眼在臂上
            • 眼在臂上的打磨
          • 视觉算法 [ok]
            • YOLOV5OBB
            • YOLOV8BOX
        • 设备模块 [ing]
          • 机械臂 [ok]
          • 相机
          • 传送带 [pass]
          • 末端工具
    • rk
      • 事件播报功能开发
        • play + mp3文件(通过HTTP传输)
        • clear
    • personal
      • C 实现 HTTP 服务器 [ok]
  • 12.21

    • vcr_0.5 [defer]
      • 设备和算法模块 12.21完成
        • 算法模块 [defer]
          • 作业算法
            • 眼在臂外
            • 眼在臂上
            • 眼在臂上的打磨
          • 视觉算法 [ok]
            • YOLOV5OBB
            • YOLOV8BOX
        • 设备模块 [defer]
          • 机械臂 [ok]
          • 相机
          • 传送带 [pass]
          • 末端工具
    • rk [ing]
      • 事件播报功能开发
        • play + mp3文件(通过HTTP传输)
        • clear
    • personal
      • C 实现 HTTP 服务器
      • Mongoose 实现HTTP动态请求文件和上传文件
  • 12.21

    • vcr_0.5 [defer]
      • 设备和算法模块 12.21完成
        • 算法模块 [defer]
          • 作业算法
            • 眼在臂外
            • 眼在臂上
            • 眼在臂上的打磨
          • 视觉算法 [ok]
            • YOLOV5OBB
            • YOLOV8BOX
        • 设备模块 [defer]
          • 机械臂 [ok]
          • 相机
          • 传送带 [pass]
          • 末端工具
    • rk [ok]
      • 事件播报功能开发
        • play + mp3文件(通过HTTP传输)
        • clear
    • personal [ok]
      • C 实现 HTTP 服务器
      • Mongoose 实现HTTP动态请求文件和上传文件

20231225 - 20240101

  • 12.25

    • vcr_0.5 [ing]
      • 设备和算法模块
        • 算法模块
          • 作业算法 [defer]
            • 拆码垛
            • 打磨
            • 焊接
          • 视觉算法 [ok]
            • YOLOV5OBB
            • YOLOV8BOX
        • 设备模块 [defer]
          • 机械臂 [ok]
          • 相机
          • 传送带 [pass]
          • 末端工具
      • 网络通讯
        • 制定对外接口,与后端联调
  • 12.26

    • vcr_0.5 [ing]
      • 设备和算法模块
        • 算法模块
          • 作业算法 [defer]
            • 拆码垛
            • 打磨
            • 焊接
          • 视觉算法 [ok]
            • YOLOV5OBB
            • YOLOV8BOX
        • 设备模块 [ing]
          • 机械臂 [ok]
          • 相机 [defer]
          • 传送带 [pass]
          • 末端工具 [ing]
      • 网络通讯
        • 制定对外接口,与后端联调
          • 所有设备字段相同,不一样的使用冗余字段
  • 12.27

    • vcr_0.5
      • 所有设备列表接口 [ok]
      • 相机模块开发 [ok]
      • 作业算法接口 [ok]
      • 机械臂功能接口
  • 12.28

    • vcr_0.5
      • 机械臂功能接口 [ing]
  • 12.29

    • vcr_0.5
      • 机械臂功能接口 [ing]

简介

  • 2024年工作笔记

2024.01.01 - 2024.01.07

  • 01.01

    • holiday
  • 01.02

    • vcr_0.5
      • 机械臂功能接口 [ok]
        • 机械臂id键固定字符串 [ok]
        • 机械臂单元测试速度内置 [ok]
      • 相机功能接口 [ing]
        • 相机ID和相机本身的型号ID要区分 [ok]
  • 01.03

    • vcr_0.5
      • 末端工具仅提供设置和查看接口,持久化在后端 [ok]
      • 示教点的增删改查不提供,在后端实现 [ok]
      • 增加末端工具测试接口 : 抓取-》查看状态-》释放-》查看状态
      • 末端工具是否抓取接口更改为查看设备状态
      • 各个设备模块的列表接口更换为查看指定设备的所有属性,输入设备id,输出设备属性,设备id在获取所有设备列表接口中
      • 相机模块开发
        • 获取指定相机属性
        • 获取图片
      • 视觉算法模块开发
        • 获取指定视觉算法属性
      • 作业算法模块开发
        • 获取指定作业算法属性
    • rk
      • 现场协助 东坡中学 [ok]
  • 01.04

    • rk
      • 优化任务恢复
    • vcr_0.5
      • 增加末端工具测试接口 : 抓取-》查看状态-》释放-》查看状态 [ok]
      • 末端工具是否抓取接口更改为查看设备状态 [defer]
      • 各个设备模块的列表接口更换为查看指定设备的所有属性,输入设备id,输出设备属性,设备id在获取所有设备列表接口中 [ok]
      • 相机模块开发 [ing]
        • 获取指定相机属性 [ok]
        • 获取图片 [ok]
  • 01.05

    • vcr_0.5
      • 工作流设计

2024.01.08 - 2024.01.14

  • 01.08

    • vcr
      • 任务执行,任务指令的解析,静态拆朵/码垛
      • 静态拆码垛 [defer]
    • rk
      • 对接云平台 [ing]
      • 整理离线项目 [ok]
  • 01.09

    • vcr
      • httpd服务退出方式 [ok]
      • 任务执行,任务指令的解析,静态拆朵/码垛 [ing]
  • 01.10

    • vcr
      • 任务执行,任务指令的解析,静态拆朵/码垛 [ing]
        • 启动 [ok]
        • 停止 [ok]
        • ML [ok]
        • MJ [ok]
        • 抓 [ok]
        • 放 [ok]
        • 暂停 [defer]
        • ERRNO [ok]
        • 计数器 [ok]
        • 计时器 [ok]
        • while(条件){} [ok]
        • if(条件){}else{} [ok]
        • 静态拆垛/码垛 [defer]
        • 动态抓取/码垛 [defer]
        • 打磨 [defer]
      • 任务解析器单元测试 [ok]
  • 01.11

    • vcr
      • 设备控制由网络请求改为函数调用 [ok]
      • 计数器,计时器,错误码 改为只读 [ok]
      • 增加任务接口
        • 创建
        • 删除
        • 继续
      • 增加算子
        • 计数器算子 [ok]
        • 暂停算子 [ing]
  • 01.12

    • vcr
      • 增加任务接口
        • 列表 [ok]
        • 创建 [ok]
        • 删除 [ok]
        • 继续 [ok]
      • 增加算子
        • 暂停算子 [ok]
      • 优化任务删除功能 [ok]
    • rk
      • 增加获取一张图片接口 [ok]

2024.01.15 - 2024.01.21

  • 01.15

    • 请假
  • 01.16

    • rk
      • 发货 [ok]
    • vcr
      • 比特大陆平台机械臂服务编译
        • 失败. 项目的third_party/lib/下的库文件是x86架构的,需要arm结构的
        • third_party/lib/下的第三方库
          • libOsqpEigen
          • libabsl [ok]
          • libanalogy [ok]
          • libgflags [ok]
          • libglog [ok]
          • libgmock [ok]
          • libgtest [ok]
          • liborocos-kdl [ok]
          • libospq
          • libpsos [ok]
          • libsmokey [ok]
          • libvxworks [ok]
        • apt search
          • libgtest-dev [ok]
          • libgmock-dev [ok]
          • libgoogle-glog-dev [ok]
          • libgflags-dev [ok]
          • liborocos-kdl-dev [ok]
      • 静态目标抓取算子开发
        • 检测算法模块开发
        • 抓取流程
  • 01.17

    • rk平台部署
  • 01.18

    • vcr
      • 开发任务编程功能
  • 01.19

    • vcr
      • 开发静态拆码垛算子

2024.01.22 - 2024.01.28

  • 01.22

    • vcr
      • 任务编排的算子增加末端工具设置参数 [ok]
      • 静态拆码垛算子 [ing]
  • 01.23

    • vcr
      • 静态拆码垛算子
        • 没有放置位置时,表示放置区满了,需要更新放置区,切换暂停状态,等待更新 [ok]
  • 01.24

    • vcr
      • 静态拆码垛算子
        • 没有检测到目标时,表示没有目标了,需要更新目标区,切换到暂停状态 [ok]
        • 有目标时,不回到home点,没有目标时,回到home点,并切换到暂停状态 [ok]
        • 任务状态和提示信息 [ok]
    • rk
      • 自动获取现场告警图片,用于算法升级

2024.01.29 - 2024.02.04

  • 01.29

    • rk
      • 定位告警解析线程退出的原因 [ok]
      • base64编码时,图片数据为空,断言失败
    • vcr
      • 恢复10kg 和 3kg 两个测试环境 [ok]
  • 01.30

    • vcr
      • 3kg标定,10kg标定 [ok]
      • 静态目标抓取算子测试 [ok]
  • 01.31

    • vcr
      • 动态目标抓取单元测试 [ing]
        • 速度测试 : 放弃,使用固定速度
        • 抓取流程编排
          • 段错误
  • 02.01

    • vcr
      • 解决测试用例段错误问题 [ing]
      • 固定速度,目标静态情况下,保证测试流程正常运行 [ing]
      • 检测时间的计算
      • 检测成功率低
  • 02.02

    • vcr
      • 配置文件增加抓取区域,
      • 任务参数增加检测区域,
      • 增加参数控制没有检测到目标是否进入暂停状态
  • 02.03

    • 休息
  • 02.04

    • vcr
      • 静态抓取算子调试 [ok]
      • 动态抓取算子问题修复 [ok]
        • 没有放置位置时进入暂停状态
      • 任务创建失败时,需要从内存中删除 [ok]

2024.02.18 - 2024.02.25

  • 02.18

    • rk平台
      • 录制现场视频并且拷贝 [ok]
      • 增加录制脚本 [ok]
    • vcr
      • 解决响应慢的问题
        • 增加网络层: mongoose
        • 图片有base64字符串传输改为二进制传输
  • 02.19

    • vcr
      • 增加网络层: mongoose [ok]
      • 增加网络层: boost.beast
      • 图片有base64字符串传输改为二进制传输 [暂不更改]
  • 02.20

    • vcr
      • 增加网络层: boost.beast [放弃了,太难玩了]
      • 多目标抓取 步骤混乱 [ing]
        • 同步抓取,调试放置策略
        • 放置点由关节角改为笛卡尔坐标
      • 放置策略设计
        • 先做静态的
        • 再做动态的
  • 02.21

    • vcr
      • 制定工作计划
        • 无序抓取,分为静态抓取和动态抓取。整个流程分为两步 抓取和放置。衡量单位: 抓取精度 放置策略 程序稳定性
          • 抓取精度受 标定步骤 和 点云计算 影响,与算法组合作
          • 放置策略 功能未实现
          • 程序稳定性是与后端对接 是否满足用户的所有操作
        • 最先解决的是 补齐放置策略功能 其次是程序稳定性 最后是抓取精度
        • 解决问题的顺序是
          • 同步的,静态的抓取后放置的策略
          • 同步的,动态的,已知速度的的抓取后放置的策略
          • 异步的,静态的连续抓取
          • 异步的,动态的连续抓取
      • 放置策略
        • 单点垂直放置 [ok]
          • 试验通过,存在的问题 由于抓取误差 放置位置会有偏差
        • 多点平铺放置
          • 试验通过 [ok]
        • 动态单点垂直放置 [ing]
  • 02.22

    • vcr
      • 适配新架构的vcr项目
      • Demo新的目标
        • 静态的 同步的 高精度的 三维物体的抓取和放置
        • 动态的 同步的 高精度的 低效率的 二维物体的抓取和放置
      • 当前的进度
        • 静态的 同步的 低精度的 二维物体的抓取和放置
      • 规划
        • 动态的 同步的 低精度的 低效率的 二维物体的 抓取和放置 [ing]
          • 末端工具释放时间点过早
          • 增加放置策略:放到传送带前面,自动循环抓取和放置
        • 静态的 同步的 高精度的 三维物体的抓取
          • 姿态的控制
          • 抓取向目标运动的控制
            • 空间中直到某一点的坐标xyz,其平面的法向量,求垂直于平面且穿过该坐标的直线上的某一点的坐标
        • 静态的 同步的 高精度的 三维物体的放置
          • 姿态的控制
        • 动态的 同步的 高精度的 二维物体的抓取和放置
  • 02.23

    • vcr
      • 规划
        • 动态的 同步的 低精度的 低效率的 二维物体的 抓取和放置 [ok]
          • 末端工具释放时间点过早 [ok]
          • 增加放置策略:放到传送带前面,自动循环抓取和放置 [ok]
        • 静态的 同步的 高精度的 三维物体的抓取 [ing]
          • 姿态的控制 [由joint改为cart]
          • 抓取向目标运动的控制 [待集成]
            • 空间中知道某一点的坐标xyz,其平面的法向量,求垂直于平面且穿过该坐标的直线上的某一点的坐标
    • 机器学习
      • pytorch框架 -> ONNX : 训练
      • ONNX -> tensorRT : 部署
  • 周报

    • 本周工作:
      • 完成两种静态抓取的放置策略: 基于空间中固定点的垂直放置和平铺放置
      • 完成三种动态抓取的的放置策略:基于空间中固定点的垂直放置,平铺放置和单点放置
      • 正在解决空间中,静态的,多个堆叠的,三维目标的抓取
    • 下周计划
      • 解决空间中,静态的,多个堆叠的,三维目标的抓取,分为两步
        • 对目标姿态的控制
        • 对目标抓取和放置的流程控制
      • 与python后端联调

2024.02.26 - 2024.03.03

  • 02.26

    • vcr
      • 运动的 同步的 高精度的 三维物体的抓取
        • 测试
      • 静态的 同步的 高精度的 三维物体的抓取 [ing]
        • 姿态的控制 [深入学习姿态控制理论]
          • 不是流程的问题 目标检测得到的姿态 超过一定角度 就会反转 目前测试的,以传送带为x轴 垂直于传送带为y轴 则在三象限内正常(面对大门为x负)
        • 抓取向目标运动的控制 [ok]
          • 空间中知道某一点的坐标xyz,其平面的法向量,求垂直于平面且穿过该坐标的直线上的某一点的坐标
    • machine learning
      • pytorch框架 -> ONNX : 训练
      • ONNX -> tensorRT : 部署
  • 02.27

    • vcr
      • 优化放置策略的工作流程 避免物体旋转时打乱其他物体 [ok]
      • 深入学习姿态控制理论 [ing]
  • 02.28

    • vcr
      • 学习姿态的四元数表达和姿态差的计算
  • 02.29

    • vcr
      • 优化任务配置参数,使部分参数变为可选 [ok]
      • 学习姿态的四元数表达和姿态差的计算
        • 可以控制机械臂绕指定轴向指定方向(正/负)旋转指定角度 [ok]
          • 使用轴角的方式 旋转角的大小和正负来控制旋转的大小和方向,旋转轴来指定需要绕这旋转的轴
          • 当前姿态的矩阵左成需要旋转的偏移旋转矩阵,则参考坐标系为基坐标系
          • 试验的出 右乘是没有意义的,且左成需要旋转的姿态已经够用于当前业务操作
  • 03.01

    • vcr
      • 更新pcl算法,增加目标物体六个面中心点的输出 [ok]
      • 将相对姿态控制加入0.5版本 [ok]
        • 通过任务编排参数进行控制
      • 测试0.5版本,进行封版,后续和后端联调 [ok]
  • 周报

    • 本周工作:
      • 完成空间中,静态的,多个堆叠的,三维目标的抓取:由固定的沿Z轴方向抓取 改为 垂直于目标平面动态的抓取
      • 解决三维目标放置姿态的控制问题:输入需要绕三个基坐标系的正交轴旋转的角度,即可运动到最终姿态
      • 测试0.5版本的静态抓取和动态抓取,代码打上标签并提交到git,程序部署到测试机器用于演示和后端联调
    • 下周计划:
      • 配合后端调试
      • 开始新版本vcr的项目开发
    • 帮助:
      • python后端
      • 与工程组配合,开发各个功能模块

2024.03.04 - 2024.03.10

  • 03.04

    • vcr
      • 机械臂模块 – robot
      • 任务执行模块 – job
      • 管理模块 – master
    • rk
      • 山东客户部署
  • 03.05

    • 机械臂模块 – robot
      • 这个模块必须具备什么特性
        • 可以指定初始化的配置文件,这个配置文件有一个默认路径,这个配置文件旧版本是以JSON格式存储,新版本计划以yaml格式存储 [ok]
        • 管理不同型号的机械臂
        • 每个机械臂有一个状态,在这里加入状态机的概念
        • 机械臂运行时资源和静态资源需要有一个映射关系,静态资源对外来说是一个设备id,运行时资源对内来说是一个对象
  • 03.06

    • 完成机械臂模块 – robot
      • 抽象设备层完成 [ok]
      • 网络通讯层 [ing]
  • 03.07

    • 完成机械臂模块 – robot
      • 网络通讯层 [ok]
    • 完成管理模块 – master
      • 网络通讯层
  • 03.08

    • 机械臂模块 – robot
      • 通讯协议文档 [ok]
    • 管理模块 – master
      • 网络通讯层 [ing]
    • 任务模块 – task
      • 层次结构设计
    • 模型推理
      • 加载eigne文件
  • 本周工作

    • 完成新版本VCR项目中机械臂模块的开发,且部署到测试机器
    • 正在开发管理模块
  • 下周计划

    • 完成管理模块和任务模块的开发

2024.03.11 - 2024.03.17

  • 03.11

    • vcr
      • 任务模块 – job
        • 功能设计
          • 设计任务参数存储的数据结构 [ok]
  • 03.12

    • vcr
      • 任务模块 – job
        • 功能设计
          • 设计任务参数存储的数据结构 [ok]
          • 任务的增删改查实现 [ok]
        • 网络通讯层
          • 协议开发 [ok]
      • 管理模块 – master
        • 功能设计
          • 设计各个模块数据存储的数据结构[ing]
    • rk
      • 上报平台协议开发
  • 03.13

    • vcr
      • 任务模块 – job
        • 解决task层内部与其他节点通讯问题 [ok]
          • 在task命名空间中新增工具类,继承TIPC类,根据task需要的接口定制开发,最终作为task类的成员变量提供功能
      • 管理模块 – master
        • 功能设计
          • 设计各个模块数据存储的数据结构[ing]
            • 设备清单
    • rk
      • 上报平台协议开发 ing
        • libuv
        • boost.beast
  • 03.14

    • vcr
      • 管理模块 – master
        • 设备清单 [ok]
        • 机械臂模块内部通讯 [ok]
  • 03.15

    • vcr
      • 管理模块 – master
        • 相机模块 [ok]
        • 工具模块 [ok]
        • 任务模块 [ok]
          • 任务执行模块待完成
    • rk
      • 需求
        • 3月22日之前 完成常州建科院的协议对接 阶段为 开发阶段和调试阶段
        • 加班时间 每天 19 - 21, 10h : 800rmb
      • 开发阶段
1
2
3
4
5
6
7
8
9
{
"AiDatoDto": {
"deviceNo": "设备编号",
"?warnType": "1 未戴安全帽,2 未穿反光衣,3 区域入侵,4 烟雾明火识别, 5 人员超载",
"warnType": 1,
"warnAt": "抓拍预警时间",
"warnPic": "抓拍图片url"
}
}
    + 响应示例:
1
2
3
4
5
6
{
"msg": "string",
"code": "string",
"data": {},
"success": true
}
  • rk

  • 03.16

    • rk
      • 使用httplib库
        • 解决token申请的问题 [ok]
        • 解决form表单同时提交图片和字符串的问题(Content-Type: multipart/form-data) [ok]
      • 工程化测试代码
        • 图片保存路径的拼接 [ok]
          • 年月日,时分转字符串 [ok]
        • token申请功能封装 [ok]
      • 问题:
        • token申请成功,推送事件返回token无效 [ing]
      • 升级管理平台数据库表 [ing]
        • 增加字段表示上报平台的协议
          • 南京傲途
          • 常州建安
  • 本周工作

    • 任务模块的开发:除了任务执行命令正在开发,其他命令都已完成
    • 管理模块的开发:完成了与任务模块,相机模块,工具模块,机械臂模块的对接和调试
  • 下周计划

    • 完成管理模块和推理模块的对接和调试
    • 完成管理模块和后端的对接和调试
    • 完成任务模块的任务执行命令

2024.03.18 - 2024.03.22

  • 03.18

    • vcr
      • 管理模块
        • 和后端的HTTP通讯 [ok]
          • mongoose [ing]
            • 线程池[ing]
          • httpd2.0
          • myhttpd
        • 和推理模块的对接和调试
    • rk
      • 告警信息上报返回404? [ing]
  • 03.19

    • vcr
      • 管理模块
        • 各模块http通讯[ok]
      • 任务模块
        • 虚拟的 唯一的 设备id [ok]
    • rk
      • 告警信息上报返回设备编号不能为空 [ok]
      • 设备不存在
  • 03.20

    • vcr
      • 任务模块
        • 任务执行 [ing]
    • rk
      • 设备不存在 [ok]
      • token路径和上报路径的拼接和拆解 [ok]
  • 03.21

    • vcr
      • 任务模块
        • 任务执行[ing]
    • rk
      • 画告警框 [ok]
      • 新版本部署和镜像制作
  • 03.22

    • vcr
      • 注册命令改为广播 [ing]
        • 解决任务模块使用其他模块通讯地址的问题 [ok]
      • 任务模块
        • 任务执行[ing]
          • start [ok]
          • stop [ok]
          • move_line [ok]
          • move_joint [ok]
          • catch [ing]
          • release
          • pause
          • sleep
          • error_number
          • timer
          • counter
          • while算子
          • if 算子
          • static_catch
          • dynamic_catch
    • rk
      • 新版本部署和镜像制作 [ok]
  • 本周工作

    • 任务模块的开发: 接口都已实现,正在开发任务执行功能
    • 管理模块的开发: 完成HTTP层开发,正在对接和调试任务执行功能
  • 下周计划

    • 完成任务模块的任务执行
    • 完成管理模块和推理模块的对接和调试
    • 进行后端整体联调

2024.03.25 - 2024.03.31

  • 03.25

    • vcr
      • 任务模块
        • release [defer]
        • pause [ok]
        • sleep [ok]
        • error_number [defer]
        • timer [defer]
        • counter [ok]
        • while算子 [ok]
        • if 算子 [ok]
        • static_catch
        • dynamic_catch
      • 推理模块
        • 内部模块命令调试[ok]
    • rk
      • 模型部署工具 [ing]
  • 03.26

    • vcr
      • 任务模块
        • static_catch
        • dynamic_catch
      • 推理模块
        • 联调 [ing]
        • 新协议文档对接 [ok]
    • rk
      • 整理工地小盒子,输出文档 [ing]
      • 数据库的设计
  • 03.27

    • vcr
      • 任务模块
        • catch [ok]
        • release [ok]
        • static_catch
        • dynamic_catch
      • 推理模块
        • 联调 [ok]
      • 相机模块
        • 获取图片(base64编码的字符串) [ok]
    • rk
      • 在mnc的基础上实现离岗检测业务 [ing]
        • 检测区域固定 检测目标只有两种状态: 有和无
      • 修复音柱平台发送请求失败的问题
        • 由httplib更换为curl [ok]
  • 03.28

    • vcr
      • 管理模块
        • 机械臂模块
          • 设备信息接口 [ok]
        • 任务模块
          • 设备状态 [defer]
          • static catch [ing]
            • 机械臂正解,逆解 [ok]
            • 推理模块目标信息的获取 [ok]
            • 抓取流程编写 [ing]
        • 推理模块
          • 设备状态 [defer]
    • rk
      • 实现离岗检测业务
        • 监测区域内有目标就刷新时间戳,没有就根据上一次时间戳算出时间间隔与阈值进行判断 [ing]
  • 03.29

    • vcr
      • 任务模块
        • 完成静态抓取 [ok]
          • 姿态的控制 [ok]
          • 垂直于目标平台向上运动
            • 等待推理模块增加法向量数据
          • 放置策略重构 [ing]
        • 空间中一点在三维物体中的判断算法 [defer]
  • 本周工作

    • 完成了任务模块的任务执行功能开发
    • 完成了管理模块和推理模块的对接和调试
    • 正在开发任务编排功能
  • 下周计划

    • 完成任务模块的任务编排功能,实现静态拆码垛算子和动态无序抓取算子
    • 整体联调,部署在测试机器进行演示
  • 03.30

    • rk
      • 离岗检测业务设计
        • 告警阈值 [ok]
        • 告警间隔 [ok]
        • 目标区域 [ok]
          • 图像显示不正确,需要前端查看
        • 保存告警图片 [ok]
          • 有目标的最后一张图片
          • 没有目标的最后一张图片
        • 保存告警视频 [ok]
          • OpenCV的方式保存图片 [ok]
          • OpenCV 图片合成视频 [ok]
        • 离岗后,回岗检测 [ing]

2024.04.01 - 2024.04.07

  • 04.01

    • vcr
      • 静态拆码垛
        • 任务属性增加要抓取的目标索引 [ok]
        • 解决任务删除接口问题 [ok]
        • 码垛策略 [ok]
        • 抓取区域
    • rk
      • 告警数据存储数据库 [ok]
      • 传输告警视频文件 [ok]
      • 离岗后,回岗检测 [ing]
      • 告警上报 [defer]
        • 如何传输告警视频文件到云平台
  • 04.02

    • vcr
      • 静态拆码垛
        • 抓取区域 [ok]
          • 最大点和最小点
        • 任务参数重构 [ok]
    • rk
      • 云平台接入
        • 告警增加查看告警图片接口 [ok]
        • 告警增加获取告警列表接口(由POST转为GET) [abandon]
  • 04.03

    • vcr
      • 推理模块加到任务模块,对外屏蔽,对内根据算子类型选择 [ok]
        • 拆码垛算子 – 图像分割任务
      • 静态拆码垛业务联调 [defer]
    • rk
      • gh-rk-1013 升级 [ok]
      • gh-rk-1012 增加磁盘容量检测脚本 [ok]
      • 文件系统损坏问题排查 [ing]
      • 回岗,离岗两个独立的事件 [ok]
      • 离岗,回岗视频增加文字 [ok]
  • 本周工作

    • 完成静态拆码垛算子的开发
    • 正在进行与后端联调
  • 下周计划

    • 完成动态无序抓取算子的开发
    • 整体联调,部署在测试机器进行演示
  • 04.07

    • vcr
      • 静态拆码垛业务联调 [ing]
        • 静态拆码垛算子死锁问题 [ing]
        • 解决静态抓取算子和推理模块对接的问题
    • rk
      • 常州建安平台远程更新 [ok]
    • leave-job
      • 减少告警视频的存储大小 [ing]
        • 5分钟的告警视频 8.2MB左右

2024.04.08 - 2024.04.14

  • 04.08

    • vcr
      • 静态拆码垛业务联调 [ok]
        • 将目标数据增加到任务属性接口中
    • rk
      • 断电问题复现
    • leave-job
      • 减少告警视频的存储体积 [ok]
        • 1280 * 720 –》 640 * 360 && 2fps == 5.2MB左右
      • rk平台部署 [ok]
      • 视频格式转换 [ok]
        • jpeg格式转mp4格式
    • 软件设计师
      • 视频教程
    • 技能储备
      • 图像处理加速技术
        • GPU
  • 04.09

    • vcr
      • 任务属性接口增加放置点位姿 [defer]
      • 动态抓取流程编写 [ing]
    • rk
      • 断电问题复现: 使用自动重启脚本模拟断电的情况
      • 发现了问题
        • 使用自动重启脚本后,在docker停止容器后,发现了structure needs clean问题
        • 修复的步骤

示例代码

+ 制作带有云平台的docker镜像 [ing]
  • leave-job

    • 项目编码mp4失败问题
    • JPEG编码,avi封装的视频–》H264编码,mp4封装的视频(ffmpeg命令行版本)[ok]
  • 技能储备

    • CUDA编程
  • 04.10

    • vcr
      • 动态抓取流程编写[ok]
    • 模型部署
      • yolov5.onnx模型部署 [defer]
        • 学习来没有头绪,需要规划
    • rk
      • 断电问题复现和解决方案的生成
    • leave-job
      • rk平台部署 [ok]
      • 任务参数的设计
  • 04.11

    • vcr-机场行李箱抓取demo
      • 机械臂的控制 [ok]
      • 电动吸盘的控制 [ok]
    • rk
      • 断电问题复现和解决方案的生成
    • leave-job
      • 前端界面修改统计[ok]
      • 任务参数的设计 [ok]
  • 04.12

    • vcr-机场行李箱抓取demo
      • 测试抓取一个行李的耗时 [ing]
      • 接入算法 [defer]
    • 技能储备
      • 网络通讯
        • 二进制文件上传和下载:
        • 图片, [ok]
        • 视频,
        • 文件,
        • 压缩包

2024.04.15 - 2024.04.21

  • 04.15

    • vcr-机场行李箱抓取demo
      • 算法工程化 [ing]
    • rk
      • 制作新版本镜像 [ing]
        • 修复常州建安相关问题
          • 上报告警图片地址不正确
          • 上报平台地址由测试地址改为正式地址
          • 修复南京傲途地址错误问题
          • 增加云平台服务
  • 04.16

    • vcr-机场行李箱抓取demo [ing]
      • 固定速度,优化抓取策略
      • 抓取策略由容器改为map,键为目标的体积,值为目标的放置点 [ing]
    • rk
      • 制作新版本镜像 [ok]
    • 技能储备
      • 网络通讯
        • 二进制文件上传和下载:
        • 图片, [ok]
        • 视频, [error]
        • 文件, [ok]
        • 压缩包 [ok]
  • 04.17

    • vcr-机场行李箱抓取demo [ok]
      • 抓取策略由容器改为map,键为目标的体积,值为目标的放置点 [ok]
      • 速度增加,目标为80% [ok]
    • 技能储备
      • 网络通讯
        • 视频, [defer]
      • kafka库学习
        • Java实现
        • C++有客户端库
        • 结论: 暂不学习
      • zmq库学习 [ing]
        • 核心由C++实现
        • 结论:推荐学习
      • redis库学习
        • 核心由C实现
        • 结论:暂不学习
      • RabbitMQ
        • 服务器由Erlang语言编写
        • 结论:暂不学习
  • 04.18

    • vcr-机场行李箱抓取demo [ing]
      • 目标跟踪 [ing]
        • 机械臂于传送带速度相同 做相对静止的运动 [ok]
    • construction vehicle(工地车辆)
      • x86平台模型转换 [ing]
      • 区域入侵-》车辆检测
      • 车辆检测业务
      • 告警推送
        • 时间
          • string
        • 车牌号
          • string
        • 图片
          • base64
        • 序列号
          • string
    • 技能储备
      • zmq库学习 [ok]
        • 多主题 多订阅模式
      • C++基础
        • std::vector 拷贝赋值 [ok]
          • std::vector::erase & std::copy
  • 04.19

    • vcr-机场行李箱抓取demo [ing]
      • 目标跟随效果优化[ing]
    • construction vehicle(工地车辆)
      • x86平台模型转换 [ok]
      • vca启动任务参数 [ok]
      • 模型配置 detector.json [ing]
      • 车辆视频模拟rtsp流
      • 区域入侵-》车辆检测
      • 车辆检测业务
      • 告警推送
        • 时间
          • string
        • 车牌号
          • string
        • 图片
          • base64
        • 序列号
          • string
    • 技能储备
      • openssl库学习

2024.04.22 - 2024.04.28

  • 04.22

    • vcr-机场行李箱抓取demo [ing]
      • 目标跟随效果优化[ing]
    • rk
      • 常州建安平台反光衣检测算法优化 [ing]
    • construction vehicle(工地车辆)
      • 模型配置 detector.json [ok]
        • 模型压缩文件上传失败问题
        • 上传未解决,使用sql语句手动添加
      • 区域入侵-》车辆检测 [ok]
        • 根据告警lable画框
      • 车辆视频模拟rtsp流 [ok]
      • 车牌信息入库 [ok]
      • 车辆检测业务 [ok]
      • 心跳 [ok]
      • 告警推送 [ok]
        • 时间
          • string
        • 车牌号
          • string
        • 图片
          • base64
        • 序列号
          • string
    • 技能储备
      • openssl库学习
  • 04.23

    • vcr-机场行李箱抓取项目 [ing]
    • 职责:机械臂,整体流程集成
      • 建立分支,规划架构
    • rk
      • 常州建安平台反光衣检测算法优化 : 拷贝视频 – gh-rk-1023 [defer]
      • ssh -o ‘proxycommand socat - PROXY:47.100.31.121:gh-rk-1023:22,proxyport=5002’ root@47.100.31.121
    • construction vehicle(工地车辆)
      • 合并工地车辆视频 [ing]
      • 优化告警推送
    • leave-job(值班室监控)
      • 制作docker镜像 [ok]
    • 技能储备
      • openssl库学习
      • zlmediakit库学习
  • 04.24

    • vcr-机场行李箱抓取项目 [ing]
    • 职责:机械臂,整体流程集成
      • 建立分支 [ok]
      • 规划架构 [ing]
        • 业务流程在master中,在一个类中实现(BaggageHandlingSystem) [ok]
        • 明确要做的内容,形成文档 [ing]
    • construction vehicle(工地车辆)
      • rk平台模型测试 [ok]
      • 增加获取平台类型表和获取平台地址表接口 [ok]
      • 心跳线程由静态变量改为从数据库读取地址 [ok]
    • 技能储备
      • windows下C++开发 [ing]
        • Microsoft Visual Studio 使用
      • openssl库学习 [defer]
      • zlmediakit库学习 [defer]
  • 04.25

    • vcr-机场行李箱抓取项目 [ing]
      • 业务具体实现有master转移到job [fail]
      • 任务模块的命令增加变长数据的大小 [fail]
      • 先从master节点开发,重新写任务相关函数 [ok]
    • construction vehicle(工地车辆)
      • 现场视频测试 [ok]
      • docker镜像制作 [ok]
      • 现场视频素材收集 [ing]
    • 技能储备
      • windows下C++开发 [ing]
        • Microsoft Visual Studio 使用
  • 04.26

    • vcr-机场行李箱抓取项目 [ing]
      • job节点,具体实现任务接口 [ok]
      • master与job联调 [ok]
    • construction vehicle(工地车辆)
      • 现场视频素材收集 [ing]
    • rk
      • 反光以检测算法升级 [ing]
        • 序列号 3b1456fc-d991-06fb-a5ce-9319876172a0 gh-rk-1023
      • 安全帽检测算法升级 [ing]
        • 序列号 7ed117d0-f489-a476-91e9-c25196190239 gh-rk-1004
        • 存储目录: /home/user/zjy-190/Videos/helmet/gh-rk-1004
    • 技能储备
      • windows下C++开发 [ing]
        • Microsoft Visual Studio 使用
  • 04.27

    • 休息
  • 04.28

    • vcr-机场行李箱抓取项目 [ing]
      • 任务属性接口问题修复 [ok]
      • 任务执行函数开发 [ing]
        • 任务执行线程创建 [ok]
        • 任务执行线程删除 [ok]
        • 任务执行线程暂停 [ok]
        • 任务执行线程继续 [ok]
        • 任务执行线程状态 [ok]
      • 机械臂控制测试 [ok]
      • 工具控制测试 [ok]
    • construction vehicle(工地车辆)
      • 现场视频素材收集 [ing]
        • gh-rk-1026
        • gh-rk-1003
      • 车辆检测模型训练 [ing]
        • /home/user/zjy-190/Videos/南京_匠造_工地车辆
        • /home/user/zjy-190/Videos/vehcile/gh-rk-1003
        • /home/user/zjy-190/Videos/vehcile/gh-rk-1026
    • rk
      • 反光衣现场视频素材收集 [ing]
        • gh-rk-1023
      • 反光衣模型训练
        • /home/user/zjy-190/Videos/gh-rk-1023
      • 安全帽现场视频素材收集 [ing]
        • gh-rk-1004
      • 安全帽检测算法升级 [ing]
        • /home/user/zjy-190/Videos/helmet/gh-rk-1004
    • 技能储备
      • windows下C++开发 [ing]
        • Microsoft Visual Studio 使用

2024.04.29 - 2024.05.05

  • 04.29

    • vcr-机场行李箱抓取项目 [ing]
      • 抓取流程模拟 [ok]
      • 急停接口实现
    • construction vehicle(工地车辆)
      • 新模型部署 [ok]
        • gh-rk-1003 [ok]
        • gh-rk-1026 [ok]
    • rk
      • 反光衣现场视频素材收集 [ing]
        • gh-rk-1023
      • 反光衣模型训练
        • /home/user/zjy-190/Videos/gh-rk-1023
      • 安全帽现场视频素材收集 [ing]
        • gh-rk-1004
      • 安全帽检测算法升级 [ing]
        • /home/user/zjy-190/Videos/helmet/gh-rk-1004
    • 技能储备
      • windows下C++开发 [ing]
        • OpenCV读取图片
  • 04.30

    • vcr-机场行李箱抓取项目 [ing]
      • 急停接口实现
        • 使用条件变量实现,修改等待方法
    • construction vehicle(工地车辆)
      • 车辆方向问题 : 只检测进入的车辆
      • 多次上报问题 : 采用车牌id过滤还是时间过滤
      • 车牌识别不准确 : 车牌识别模型训练
    • rk
      • 反光衣模型训练
        • /home/user/zjy-190/Videos/gh-rk-1023
      • 安全帽检测算法升级 [ing]
        • /home/user/zjy-190/Videos/helmet/gh-rk-1004
    • 技能储备
      • windows下C++开发 [ing]
        • opencv编译

2024.05.06 - 2024.05.12

  • 05.06

    • 请假
  • 05.07

    • vcr-机场行李箱抓取项目 [ing]
      • 对接推理接口[ing]
        • 获取目标中心点
        • 测速
    • construction vehicle(工地车辆)
      • 过滤车牌,减少误报 [ok]
      • 多次上报问题 : 采用车牌id过滤,做一个筛除
        • 用车牌作为唯一id,实现追踪算法 [ing]
      • 车牌识别模型 [defer]
        • 延后升级
    • rk
      • 优化工地盒子管理平台接口 [ok]
      • 反光衣模型训练 [defer]
        • /home/user/zjy-190/Videos/gh-rk-1023
      • 安全帽检测算法升级 [defer]
        • /home/user/zjy-190/Videos/helmet/gh-rk-1004
  • 05.08

    • vcr-机场行李箱抓取项目 [ing]
      • 对接推理接口[ing]
        • 获取目标中心点
        • 测速
    • construction vehicle(工地车辆)
      • 多次上报问题 : 采用车牌id过滤,做一个筛除
        • 用车牌作为唯一id,实现追踪算法 [ok]
    • 技能储备
      • windows下编程太难了,放弃。。。
      • 单元测试,gtest库使用 [ing]
  • 05.09

    • vcr-机场行李箱抓取项目 [ing]
      • 测试放置算法 [ok]
      • 对接推理接口[ing]
        • 获取目标中心点
        • 测速
    • 技能储备
      • 单元测试,gtest库使用 [ing]
      • 数据结构和算法基础
  • 05.10

    • vcr-机场行李箱抓取项目 [doing]
      • 对接推理接口
        • 获取目标中心点
        • 测速
    • 技能储备
      • 完善动态人脸识别项目经历
        • 拉流:测试代码中拉取视频流部分封装成类 [done]
  • 05.11

    • vcr-机场行李箱抓取项目 [done]
      • 对接推理接口
        • 获取目标中心点
        • 测速
    • 技能储备
      • 完善动态人脸识别项目经历
        • OpenCV-dnn库加载ONNX模型 [doing]

2024.05.13 - 2024.05.19

  • 05.13

    • vcr-机场行李箱抓取项目 [doing]
      • 实现抓取效果
    • 技能储备
      • 完善动态人脸识别项目经历
        • OpenCV-dnn库加载ONNX模型 [doing]
  • 05.14

    • vcr-机场行李箱抓取项目
      • 基于固定速度条件下,实现抓取效果 [done]
      • 在算法测速条件下,实现抓取效果 [undo]
        • 算法测速不准确,先用固定速度,完善抓取流程
      • 完善任务属性接口参数 [doing]
        • 计数
        • 计时
        • 任务状态
    • 技能储备
      • python YOLOV8 ONNX模型示例跑通 [done]
      • 学习示例代码,弄清楚前处理和后处理
  • 05.15

    • vcr-机场行李箱抓取项目
      • 完善任务属性接口参数 [doing]
        • 计数 [done]
        • 计时 [done]
        • 任务状态 [done]
        • 单次抓取耗时 [done]
        • 机械臂设备测试 [done]
        • 相机设备测试 [done]
        • 工具设备测试 [done]
      • 优化创建任务接口参数 [doing]
        • 增加抓取区域参数
        • 增加相机距离传送带的高度
        • 增加抓取最大高度
    • 技能储备
      • 学习示例代码,弄清楚前处理和后处理
  • 05.16

    • vcr-机场行李箱抓取项目
      • 优化创建任务接口参数 [doing]
        • 增加抓取区域参数
        • 增加相机距离传送带的高度
        • 增加抓取最大高度
    • 技能储备
      • 前处理弄清楚
  • 05.17

    • vcr-机场行李箱抓取项目
      • 优化创建任务接口参数 [done]
        • 增加抓取区域参数
        • 增加相机距离传送带的高度
        • 增加抓取最大高度
      • 对接码垛算法 [doing]
    • 技能储备
      • 搭建个人博客

2024.05.20 - 2024.05.25

  • 05.20

    • vcr-机场行李箱抓取项目
      • 前后端联调
    • 技能储备
      • 搭建个人博客
  • 05.21

    • vcr-机场行李箱抓取项目
      • 前后端联调
    • 技能储备
      • 搭建个人博客
  • 05.22

    • vcr-机场行李箱抓取项目
      • 前后端联调 [doing]
      • 标定算法接口 [done]
    • 技能储备
      • 搭建个人博客 [done]
  • 05.23

    • vcr-机场行李箱抓取项目
      • 前后端联调 [doing]
      • rk工地小盒子6-8路任务测试 [doing]
    • 技能储备
      • 个人博客增加分类功能 [done]
  • 05.24

    • vcr-机场行李箱抓取项目
      • 前后端联调 [doing]
      • rk工地小盒子6-8路任务测试 [doing]
    • 技能储备
      • 优化个人博客主页

2024.05.27 - 2024.06.02

  • 05.27

    • vcr-机场行李箱抓取项目
      • 放置算法接口
      • 角点图片接口 [done]
    • rk
      • 制作新版本docker镜像 [done]
    • 技能储备
      • 整理机器人项目
  • 05.28

    • vcr-机场行李箱抓取项目
      • 放置算法接口
    • 技能储备
      • 整理rk项目 [done]
      • 个人博客首页显示指定文章
  • 05.29

    • vcr-机场行李箱抓取项目
      • 放置算法接口,任务状态增加放置点参数 [done]
    • 技能储备
      • 个人博客首页显示指定文章
  • 05.30

    • vcr-机场行李箱抓取项目
      • 手眼标定流程测试 [done]
    • 技能储备
      • 个人博客首页显示指定文章 [done]
  • 05.31

    • vcr-机场行李箱抓取项目
      • 手眼标定流程测试 [done]
      • 任务执行流程测试 [done]
    • 技能储备
      • resume edit

2024.06.03 - 2024.06.09

  • 06.03

    • 请假
  • 06.04

    • vcr-机场行李箱抓取项目
      • 行李抓取: 提升抓取精度
      • 行李码垛:行李不少于十件,高度不少于三层
    • rk
      • 对接新中光平台 [done]
      • 对接音响 [doing]
    • 技能储备
      • resume edit
  • 06.05

    • vcr-机场行李箱抓取项目
      • 行李抓取: 提升抓取精度
      • 行李码垛:行李不少于十件,高度不少于三层
    • rk
      • 对接音响 [doing]
        • 有了思路,待对接剩余接口
    • 技能储备
      • resume edit
  • 06.06

    • vcr-机场行李箱抓取项目
      • 放置后停滞1秒 [done]
      • 增加标定板测速 [done]
      • 行李抓取: 提升抓取精度
      • 行李码垛:行李不少于十件,高度不少于三层
    • rk
      • 对接音响 [doing]
        • 有了思路,待对接剩余接口
    • 技能储备
      • resume edit
  • 06.07

    • vcr-机场行李箱抓取项目
    • rk
      • 对接音响 [doing]
        • 有了思路,待对接剩余接口

2024.06.10 - 2024.06.16

  • 06.10

    • 放假
  • 06.11

    • vcr-机场行李箱抓取项目
      • 任务属性接口增加长宽高和重量,增加装载率 [done]
      • 创建任务接口增加虚拟数据参数,3D码垛算法任务 [doing]
    • rk
      • 解决检测区域问题 [defer]
      • mnc增加隽声音柱平台 [done]
  • 06.12

    • vcr-机场行李箱抓取项目
      • 创建任务接口增加虚拟数据参数,3D码垛算法任务 [doing]
    • rk
      • 解决检测区域问题 [defer]
  • 06.13

    • vcr-机场行李箱抓取项目
      • 创建任务接口增加虚拟数据参数,3D码垛算法任务 [doing]
    • rk
      • 解决检测区域问题 [defer]
      • gh-rk-2002
        • 反光衣数据采集和算法升级
  • 06.14

    • vcr-机场行李箱抓取项目
      • 代码封版 [done]
    • rk
      • 解决检测区域问题 [done]
      • gh-rk-2002
        • 反光衣数据采集和算法升级 [defer]

2024.06.17 - 2024.06.23

  • 06.17

    • rk
      • 新镜像制作
      • 部署文档 [doing]
  • 06.18

    • rk
      • 新镜像制作 [done]
      • 部署文档 [done]
  • 06.19

    • 机械臂工控机拷贝所有数据,删除数据 [done]
    • 机械臂设置打包模式 [done]
    • rk盒子部署新镜像 [done]
  • 06.20

    • 交叉编译学习
  • 06.21

    • 简历制作

2024.06.24 - 2024.06.30

  • 06.24

    • 增加学习笔记
  • 06.25

    • 查看面试机会
  • 06.26

    • 这一天正式回家,居家学习。
    • 青瞳视觉
      • 计算机科学基础知识扎实,全面的软件知识结构,包括软件工程、操作系统、多线程、进程间通信、数据库系统、网络系统等;
    • 环境准备
      • Ubuntu环境 - 外星人电脑
      • windows环境 - 华为电脑恢复
  • 06.27

    • rk盒子调试文档
    • 准备下午五点的面试
      • 结果 问题比较浅显,不如人意
  • 06.28

    • 最后聚餐
  • 06.29

    • 阅读数据结构,算法与应用数据
  • 06.30

    • 聚餐

2024.07.01 - 2024.07.07

  • 07.01

    • 学习中间件概念,工作方向不推荐
    • 工作方向为 AI部署工程师
      • 统计boss直聘上相关工作的岗位要求,形成笔记,目标是找到学习的侧重点
      • 学习videoprocess源代码,按照岗位要求笔记有侧重点的提升
    • 后续学习方向
      • videoprocess项目吃透,做代码分析文档
  • 07.02

    • 格灵深瞳HR电话面试
    • 上海华泰线上面试,破大防了,复习C++基础
  • 07.03

    • 云蟾游戏面试,准备视频分析项目文档
    • 格灵深瞳面试准备
      • PPT四页 [doing]
        • 第一页 个人介绍
        • 第二页 视频分析盒子项目介绍
        • 第三页 机器人项目介绍
        • 第四页 人脸识别项目介绍
    • 家里项目环境搭建
      • 视频转rtsp流
      • 盒子跑任务
  • 07.04

    • 格灵深瞳面试准备
      • PPT四页 [done]
        • 第一页 个人介绍
        • 第二页 视频分析盒子项目介绍
        • 第三页 机器人项目介绍
        • 第四页 人脸识别项目介绍
  • 07.05

    • 格灵深瞳面试
  • 07.06

    • 游泳+购物
  • 07.07

    • 同学聚餐

2024.07.08 - 2024.07.14

  • 07.08

    • 面试蔚来测试开发岗位
    • 基础环境搞崩了
    • 裸土覆盖算法对接搁置
  • 07.09

    • 卸掉游戏 [done]
    • 给三三洗澡 [done]
    • 安装nvidia显卡驱动 [done]
  • 07.10

    • 去看了上海慕尼黑电子展
      • 没有更多的实际收获,但是锻炼了参加多人场所的能力和交流的能力
    • 安装cuda 和 tensorrt环境 [done]
  • 07.11

    • 写一个cuda测试
  • 07.12

    • 拷贝工地项目代码
    • 搭建编译环境 [done]
      • 实现vca编译
      • 实现mnc编译
    • rk
      • 裸土覆盖算法对接
      • 新平台推送协议开发
  • 07.13

    • 搭建流媒体服务器
      • 暂且搁置,先对接接口
    • rk
      • 裸土覆盖算法对接
      • 新平台推送协议开发 [doing]
        • 发送HTTP请求是,查询参数和body数据同时发送 [undo]
  • 07.14

    • rk
      • 裸土覆盖算法对接
      • 新平台推送协议开发 [doing]
        • 发送HTTP请求是,查询参数和body数据同时发送 [done]

2024.08.15 - 2024.07.21

  • 07.15

    • rk
      • 裸土覆盖算法对接
        • 算法配置 [done]
        • vca模型加载和结果输出 [done]
        • mnc业务开发 [done]
      • 新平台推送协议开发 [doing]
        • 发送HTTP请求是,查询参数和body数据同时发送 [done]
        • 16号联调
  • 07.16

    • rk
      • 新平台推送协议开发 [doing]
        • 联调 [done]
        • 软件包制作 [done]
      • 裸土覆盖算法对接
        • 覆盖率
          • mask掩码还原
          • 覆盖率计算
        • 区域
  • 07.17

    • rk
      • 裸土覆盖算法对接
        • 增加覆盖率 [done]
        • 增加区域 [doing]
          • 输出的掩码图,加上区域限制。遍历像素点是,首先检查该点的坐标是否在监测区域内
  • 07.18

    • rk
      • 裸土覆盖算法对接
        • 增加覆盖率 [done]
        • 增加区域 [done]
          • 输出的掩码图,加上区域限制。遍历像素点是,首先检查该点的坐标是否在监测区域内
  • 07.19

    • rk
      • 制作新镜像 20240719 [done]
  • 07.20

    • 休息
  • 07.21

    • 休息

2024.07.21 - 2024.07.28

  • 07.21

    • C++ STL基础
      • 阅读《C++20高级编程》
  • 07.22

    • rk [done]
      • 新平台对接和裸土覆盖功能交付
    • C++ STL基础
      • 阅读《C++20高级编程》
  • 07.23

    • C++ STL基础
      • vector 视频教程
  • 07.24

    • 心态
      • 稳住心态,梳理下一份工作的期望 [done]
    • C++ STL基础
      • 容器部分复习完,通过视频总结 [done]
    • 面试
      • 7月25日 云冀智行 showmebug平台
      • 7月26日 鑫剑科技 现场面试
    • 日常生活
      • 199 乐游票
        • 购买,激活后是否可以退票?
    • 未来就业方向(已确定)
      • CUDA, CUDNN, NVIDIA, TensorRT –> 高性能计算,异构编程,并行计算
  • 07.25

    • C++ STL基础
      • 关联式容器复习 [done]
      • 通过视频总结 [done]
    • 面试
      • 7月25日 云冀智行 showmebug平台 [done]
      • 7月26日 鑫剑科技 现场面试 [done]
    • 日常生活
      • 199 乐游票
        • 购买,激活后是否可以退票?
    • 未来就业方向(已确定)
      • CUDA, CUDNN, NVIDIA, TensorRT –> 高性能计算,异构编程,并行计算
        • 学习CUDA基础知识,形成笔记
      • 在x86上,加载yolov5目标检测模型,进行推理加速。
      • 在rk平台,加载模型,学好videoprocess
  • 07.26

    • C++ 复习
      • OpenCV
      • FFmpeg
  • 07.27

    • 休息
  • 07.28

    • 休息

2024.07.28 - 2024.08.04

  • 07.29

    • 面试
      • 准备7月30日的申通面试
    • 面试中遇到的问题
      • 网络编程 poll和epoll
      • 自己写过线程池吗?
      • 自己写过HTTP服务器吗?
      • 条件变量用过,深入了解是怎么实现的吗?
    • 复盘七月份找工作的经历
  • 07.30

    • 面试
      • 准备申通面试 [done]
    • 面试中遇到的问题
      • 内存共享 memcpy() 访问方式
    • 提升
      • tensorRT学习
  • 07.31

    • 流媒体开发
      • ffmpeg 取rtsp视频流
  • 08.01

    • 面试
      • 樵戈机器人公司 C++开发面试 [done]
    • 学习
      • 进程间通讯机制之共享内存
  • 08.02

    • 学习
      • 进程间通讯机制之共享内存
      • 流媒体开发工具
        • live555
          • 编译成功,注意事项有: 编译时指定编译平台 linux-64bit;修改 config.linux-64bit脚本,加上-std=c++2a 避免编译时找不到 std::atomic_flag.test(),因为只有C++20才支持
          • 示例中rtsp客户端运行成功
        • ZLmediakit
        • srs
  • 08.03

    • 休息
  • 08.04

    • 学习
      • 流媒体开发工具
        • ZLmediakit
        • srs

2024.08.04 - 2024.08.11

  • 08.05

    • 解决cmake中静态库链接循序问题
  • 08.06

    • 解决交换空间自动设置问题 [done]
  • 08.07

    • 准备上海智能制造平台有限公司机器人软件开发岗位面试
      • 复习机器人学相关知识
  • 08.08

    • 参加上海智能制造平台有限公司机器人软件开发岗位面试
  • 08.09

    • rk
      • 调试水星安防摄像头问题
  • 08.10

    • 面试
      • 盛拓半导体–软件开发工程师(苏州)
      • Cogent高骏科技–C++音视频软件开发工程师(上海)
  • 08.11

    • 休息

2024.08.12 - 2024.08.18

  • 08.12

    • 高骏科技面试[done]
  • 08.13

    • 确定offer
  • 08.14

    • 休息
  • 08.15

    • 体检
    • 看房子
  • 08.16

    • 休息
  • 08.17

    • 准备入职
  • 08.18

    • 休息

2024.08.19 - 2024.08.25

  • 08.19

    • 入职上海特机智机器人有限公司,职位为机器人软件研发,主要负责任务模块的研发。
    • 项目背景: LNG(Liquefied Natural Gas,液化天然气)运输船建造过程中液舱的制造。制造流程大致为 划线–>碰焊–>装板。工作要求精度极高,用机器代替人工,提高精度和效率。
    • 产品: 装板机器人,碰钉机器人
    • 开发环境: windows
    • 开发工具: visual studio 2017, qt5.1.4, clion
    • 依赖库: Qt,Eigen,OpenCV,FFmpeg,spdlog
  • 08.20

    • 搭建windows下开发环境,运行项目。[done]
      • 解决依赖库未找到问题: 将未找到的依赖库拷贝到项目的cmake-build-debug下即可
    • 熟悉项目编译环境,并形成文档
      • 编译器路径: C:\Program Files (x86)\Microsoft Visual Studio\2017\Community
      • 编译器版本: visual visual 2017, 15.0
      • cmake: bundled(3.29.6)
      • build tool: ninja.exe
      • C Compiler: cl.exe
      • C++ Compiler: cl.exe
      • Debugger: Bundled LLDB(9.0)
    • 学习
      • msvc: cl.exe
      • qt: qthread, qvector, qatomicint
      • spdlog
  • 08.21

    1. 完成微信文章 常用C和C++编译器推荐 学习笔记 [done]
    2. 首先完成代码阅读笔记: 对软件功能,任务逻辑,主要函数进行说明;编制函数列表,说明函数接口,用途。[doing]
      • mainwindows.cpp [done]
      • ComInterface
        • 构造函数 [doing]
      • CRobot
      • VisionInterface
      • CTask
    3. 其次根据软件开发说明文档格式要求,完成文档编制
  • 08.22

    • 碰钉机器人软件说明书文档编写
  • 08.23

    • 碰钉机器人软件说明书文档编写 [done]
    • Qt开发指南 阅读
  • 08.24

    • Qt开发指南 阅读
  • 08.25

    • Qt开发指南 阅读

2024.08.26 - 2024.09.01

  • 08.26

    • 工作 – 状态机
      • 状态定义
        • 驼峰命名法
      • 状态结构搭建
        • switch()分支结构
    • 自我提升
      • Qt开发指南 阅读
  • 08.27

    • 工作 – 状态机
      • 完成理想情况下流程的编写 [done]
      • 不理想情况下流程的编写
      • 类的表达方式改为函数
  • 08.28

    • 工作 – 状态机
      • 不理想情况下流程的编写 [done]
      • 类的表达方式改为函数 [done]
      • 流程整合 [done]
      • 遥控器数据结构定义 [doing]
      • 遥控器数据处理流程编写
  • 08.29

    • 工作 – 状态机
      • 遥控器数据结构定义 [done]
      • 遥控器数据处理流程编写 [done]
  • 08.30

    • 工作 – 调试大机器人
      • 减速比校准
      • 零位校准
    • 自我提升
      • python爬取boss职位信息
  • 08.31

    • 自我提升
      • python爬取boss职位信息 [done]
        • 获取boss直聘第一页所有职位的岗位介绍和要求信息
  • 09.01

    • 思考下一步要学习的方向
      • 设计模式
      • 软件工程
      • 机器人软件研发技术栈
        • 硬件基础是机械臂
        • 行业知识
        • Qt开发

2024.09.02 - 2024.09.08

  • 09.02

    • 工作
      • 增加视觉算法命令转换函数 [done]
      • 根据参数修改RobotParameter.h [done]
      • 遥控器控制编写 [doing]
  • 09.03

    • 工作
      • 遥控器控制编写 [done]
    • 设计模式
      • 单例模式学习
    • 提升
      • Effective Modern C++ 中文版学习
  • 09.04

    • 工作
      • 调试
  • 09.05

    • 工作
      • 调试
  • 09.06

    • 工作
      • 调试
  • 09.07

    • 图书馆学习
      • C++程序设计:标准库
  • 09.08

    • 图书馆学习
      • C++程序设计:标准库

2024.09.09 - 2024.09.15

  • 00.09

    • 工作
      • 解决日志中文乱码问题 [done]
        • 新增加的中文日志不乱码
        • 重新编译
      • 工控机长按显示右键修改为长按 [done]
        • 打开控制面板 –》 笔和触摸 –》笔选项 –》 按下并保持 –》设置
      • 测试archive包是否可用 [done]
        • 不可用
  • 09.10

    • 出差
  • 09.11

    • 出差
  • 09.12

    • 出差
  • 09.13

    • 出差结束
    • 工作:
      • 最新代码合并 [done]
      • 状态机模块更新
        • 日志更新 [done]
        • 装板机器人状态机模块开发
          • 贴合状态框架搭建 [done]
  • 09.14

    • 工作
      • 机器人bug修复,代码三个分支同步 [done]
      • 手动模块 举升位置分为两个阶段,先判断0-8个轴是否到达B点,到达之后再单独控制9轴运动
      • 下午调试倍福控制器
    • 其他
      • 解决vscode 代码无法补全问题
  • 09.15

    • 放假

2024.09.16 - 2024.09.22

  • 09.16

    • 放假
  • 09.17

    • 放假
  • 09.18

    • 工作
      • 合并最新代码
    • 其他
      • 熟悉visual studio开发
  • 09.19

    • 工作
  • 09.20

    • 合并最新代码
    • 获取放板位和碰钉位
    • 学习SVN
  • 09.21

    • 放假
  • 09.22

    • 放假

2024.09.23 - 2024.09.29

  • 09.23

    • 工作
      • 模拟传感器数据测试任务流程 [done]
      • 工装硬件测试
  • 09.24

    • 工作
      • 工装硬件测试
      • IO板调试
  • 09.25

    • 工作
      • 现场调试
  • 09.26

    • 定时器实现
    • 找到一个更好的方法替换计数法,需要解决的问题:
      • 启动一个设备,瞬时启动,但不知道什么时间停止。所以约定一个时间段,当走完时间段即表示设备运动结束,给出一个信号。
      • 在设备运行期间,主线程不会阻塞,可以随时终止设备的运行
      • 设备运行结束后主线程可以知道设备结束了
  • 09.27

    • 结束
  • 09.28

    • 休息
  • 09.29

    • 休息

2024.09.30 - 2024.10.07

  • 国庆假期,拉萨游玩

2024.10.08 - 2024.10.13

  • 10.08

    • 工作
  • 10.09

    • 出差
  • 10.10

    • 出差
  • 10.11

    • 完成C++程序设计语言-第四部分标准库图书的阅读和笔记
  • 10.12

    • 出差
  • 10.13

    • qt
    • ROS
    • 机器人学理论知识
    • 线性代数
    • 开始网络日记工作
    • 开发能力与平台无关,而与算法和数学能力有关
    • RPC框架
    • 机械臂在影视行业的应用

2024.10.14 - 2024.10.20

  • 10.14

    • 装板流程修改
    • 参数配置功能
      • yaml配置文件
    • 软著编写
  • 10.15

    • 参数配置功能 [done]
      • yaml配置文件
    • 软著编写
      • 填写源码 [done]
    • 装板流程修改 [doing]
      • 待讨论
  • 10.16

    • 使用python实现SVN和Git的代码文件同步脚本
      • 不如手动方便
    • 贴合阶段优化
      • 新方案的设计 [done]
      • 新状态实现 [doing]
  • 10.17

    • 贴合阶段优化
      • 新状态实现 [done]
    • 绝缘板安装软件用户手册 [doing]
  • 10.18

    • 绝缘板安装软件用户手册 [done]

2024.10.21 - 2024.10.27

  • 10.21

    • 参数配置文件
      • 加载接口
      • 将GVL已知的参数都移到配置文件中
  • 10.22

    • 上午配合李工调试问题
      • 复现机器人上电梯掉使能
    • 下午开会
  • 10.23

    • 机械变动后,在修改后的算法模型之上测试各个轴的运行状况。
    • 将两个机器人的两个轴都调试好,零位标定好
  • 10.24

    • 解决右轮驱动器38.1问题,限位问题 [done]
    • 将装板机器人每个轴调试好,下位机可以正常运行 [done]
      • 过速度保护
        • 升降 3.5
        • 腰转 5
        • 伸缩 13.5
        • 工具升降 3
      • 问题
        • 减速比不对,以上关节在twincat上走1mm,实际走约10mm
      • 方法
        • 减速比缩小十倍
    • 测试装板流程。
      • 测试调平流程
      • 测试对边流程
      • 测试贴合流程
    • 工作
      • 线性代数,串联机器人。
  • 10.25

2024.10.28 - 2024.11.03

  • 本周目标

    • 装板机器人流程测试完,总结问题,形成文档
    • 碰钉机器人增加新功能,修改机器人模型。
      1. 优先把过程解决完,尽量周三之前用完
      2. 施教点保存,准备,举升,退出。三个场景,顶部,侧板,斜板。
      3. 碰钉机器人修改运动模型
  • 10.28

    • 装板机器人
      • 测试各个轴是否准确正常 [done]
        • 找到升降,腰转,伸缩,工具升降运动参数不对的原因:串口调试参数60092h是以十六进制修改,由8388608改为10000
      • 测试装板流程
        • 调平
        • 对边
        • 贴合
        • 退出
  • 10.29

    • 测试装板流程
      • 调平 [done]
      • 对边 [done]
        • 问题:运动方向不对,应该沿基座标系Z轴正方向运动,实际是负方向运动。
        • 方法:相机顺序按照新的末端坐标系调整
      • 贴合 [done]
        1
        2
        3
        4
        初次备份,装板流程调试:调平,对边,贴合完成。
        后续工作:
        1. 解决因为延迟导致贴合阶段举升运动有可能出现中止问题
        2. 验证贴合精度和贴合效果
      • 退出
    • 总结装板机器人遇到的问题,形成文档 [done]
      • 软件开发/装板机器人/装板机器人存在的问题.docx
    • 合并最新代码 [done]
    • 碰钉机器人 [doing]
      • 施教点保存,准备,举升,退出。三个场景,顶部,侧板,斜板。
      • 碰钉机器人修改运动模型
        • 修改robot.cpp
        • 修改点激光顺序和摄像头顺序
          • 优化点激光更新程序
  • 10.30

    • 碰钉机器人
      • 施教点保存,准备,举升,退出。三个场景,顶部,侧板,斜板。
        • 参数配置文件增加参数 [done]
        • 定义数据结构并解析 [done]
        • 应用到软件。在软件启动时,弹出选择框,选择工作场景: 顶部,侧板,斜板.之后才可以操作。[done]
        • 示教点保存测试 [done]
      • 碰钉机器人修改运动模型
        • 修改robot.cpp [done]
          • m_freedom
        • 修改parameter.h [done]
          • LINK_FREEDOM
        • 修改robot.cpp:172行 [done] [重要!!!]
          • m_Freedom + 1 –> m_Freedom + m_ToolFreedom
        • 修改点激光顺序和摄像头顺序 [done]
          • 优化点激光更新程序 [done]
          • 优化视觉数据更新程序 [done]
      • 举升位
        • 腕转速度加大,举升位置增高,保证到达举升位时点激光一定有数据,且可执行调平
      • 下位机
        • 限制加速度,加加速度,防止启动时速度增加过快。加速度为额定速度的两倍,加加速度为加速度的三倍,
      • 界面
        • 使能按钮增大
        • 右上角三个点删除
        • 增加状态机显式 中文,按钮反馈 完成之后变绿
        • 触屏按钮测试
        • 地盘控制方向反了 下发命令的修改
        • 点激光数据显式底色 使清晰一点
        • 开发者模式–》配置模式
      • 视觉
        • 增加自动标定功能,制作标定板,在开发者模式下能够对每个相机进行标定
  • 10.31

    • 碰钉机器人
      • 界面点动速度参数加入到配置文件中
      • 碰钉机器人运动控制调试
        • 运动模型修改后,各轴运动和末端运动是否正确 [done]
        • 设置下位机加速度,加加速度 [done]
        • 地盘控制方向修正
        • 限位提示
        • 配置文件分为只读配置文件和可写配置文件 [done]
          • 只读参数
          • 可写参数
    • 完成明天的项目进度汇报PPT [done]
  • 11.01

    • 碰钉机器人
      • 合并最新代码,测试各关节运动情况
      • 界面点动速度参数加入到配置文件中
      • 检查VS2022文件编码问题

2024.11.04 - 2024.11.10

  • 11.04

    • 机器人左右轴 正方向是向左运动
    • 碰钉机器人作业流程调试完成,能够进行碰钉
    • 辅助张工进行末端工装的精度校准
  • 11.05

    • 碰钉机器人
      • 侧板情况,锁定前后轴,测试作业情况,是否可以完成
        • robot.cpp : 183
      • 行走过程中右轮突然掉使能,导致机器人整体往左旋转
      • 侧板不能磁铁吸合
    • 我原本是做机器人的,后来被裁员,感觉对电池仿真软件感兴趣,
    • 将来想做仿真软件开发,对电池反应机理与仿真相关的知识理解,学习这个行业知识,基于
  • 11.06

    • 测试作业流程,完成
  • 11.07

    • 现场作业
  • 11.08

    • 现场作业

2024.11.11 - 2024.11.17

  • 11.11

    • 重连过程,接收超时增加日志,发送超时增加
    • 打磨,机械上问题,磁铁
  • 今天过去

    • 压力测试,焊接板子,标记焊机和焊枪
    • 侧板测试,张工辅助查看机械问题,是弹簧问题还是工装问题
    • 上斜面,可达性
    • 磁铁伸出,顶住板壁,测试吸合前后相对于边线框是否发生偏差
    • 现场逐渐由桂干联系。
    • 作业优化
      • 串行改为并行
      • 安全限制
        • 车子和机械臂可以分开移动()
        • 行走轮下使能后,错误保护(warning)
      • 一键行走[待考虑]
  • 11.12

    • 现场作业
  • 11.13

    • 完成现场测试,并形成ppt:2024-11-11现场测试.pptx [done]
      • 上斜板测试
      • 侧板测试
      • 拉力测试
    • 开会记录
      • 侧板情况,磁铁下垂问题
      • 打磨效果不好问题
    • 碰钉机器人优化
      • 安全限制
        • 车子和机器人可以分开控制
        • 行走轮一个下使能后,错误保护 [done]
        • 在底盘子页面增加左轮和右轮状态显式 [done]
        • 去五号楼做测试
      • 碰钉流程优化
        • 串行改为并行
      • 自动过程整合为对齐,碰钉,退出
        • 加开关:自动化 || 半自动化 [done]
        • 手动发送调平指令 –> (调平,对边, 吸合) – 手动触发碰钉指令 –> (碰钉,脱开,退出) –> 手动–就绪状态
  • 11.14

    • 碰钉机器人优化 [done]
      • 碰钉流程优化: 由102s 优化到61s
    • 测试轮子保护
  • 11.15

    • 碰钉流程优化测试 [done]
      • 输出每个节点发送的指令集
    • 准备下周工作汇报ppt [done]
    • 优化个人博客
      • windows下docker配置jekyll环境,能够运行demo并在浏览器访问
      • 在docker中运行github个人博客项目,并能够访问
      • 能够在编辑器中修改代码

2024.11.18 - 2024.11.24

  • 11.18

    • 碰钉作业操作流程
    • 针对流程,优化软件
    • 装板机器人测试
    • 项目管理
      • 代码格式化
      • 文件编码
  • 11.19

    • 碰钉作业操作流程
      • 完成简要版本和详细版本的操作流程图 [done]
      • 消息提示框
        • 技术实验 [done]
        • 状态转换,轴限位都加上
    • 明确目标
      • 检查作业流程,列出需要注意的事项,解决一些作业上影响效率的问题,形成文档,使现场应用人员可以通过文档操作机器人顺利完成碰钉作业
      • 周四出差去江南,我来测试作业流程,测试打磨效果,碰钉流程。没有问题之后,交由现场应用人员操作。在效率测试时,主要有现场应用人员操作,我辅助。
    • 提示
      • 状态机显示,状态跳转时,给出提示,明显的提示
      • 发送错误指令时,给出警告
    • Qt学习
      • qt消息循环机制
      • QML使用经验
      • opengl,opencv
      • qt各类控件的使用,包括 tree, list, table, chart, graphic
      • 掌握QSS样式
      • Qt内部机制,例如QObject, 信号槽机制,事件机制,绘图,多线程
  • 11.20

    • 碰钉软件优化:增加消息提示框
      • 状态跳转 [done]
      • 错误提示 [done]
      • 增加点激光数据检测,线间距数据检测功能[done]
      • 完善帮助文档页面,增加文字性描述 [doing]
        • 将图片嵌入到HTML文件中 [done]
    • Qt学习
      • qt消息循环机制
      • QML使用经验
      • opengl,opencv
      • qt各类控件的使用,包括 tree, list, table, chart, graphic
      • 掌握QSS样式
      • Qt内部机制,例如QObject, 信号槽机制,事件机制,绘图,多线程
  • 11.21

    • 现场测试
      • 测试行走轮状态显示和保护 [done]
      • 新碰钉流程测试
        • 在待碰钉作业时,正确流程是发送碰钉指令和终止指令。碰钉指令继续自动流程,终止指令关闭磁铁,跳转至手动状态。
        • 问题一:
          • 也可以发送脱开指令,这样跳转到待吸合状态,目前是自动工作模式,又会自动吸合。
          • 在自动工作模式下的碰钉–待碰钉状态,如何处理脱开指令?
        • 解决方法:
          • 想法一:在这种情况下,仅支持碰钉指令和终止指令。发送碰钉指令表示继续执行;发送终止指令,表示重新执行。加上判断:当前是否是自动工作模式,如果是的话,并且收到了脱开指令,则不处理吸合指令,并且给出警告
        • 问题二:
          • 终止指令仅仅是将磁铁脱开,并不会让磁铁下降,磁铁下降是一个重复操作。这样用户在发送终止后,需要手动在开发者模式下单独控制磁铁脱开。
        • 解决方法:
          • 想法一:针对这种在碰钉–待碰钉状态下,想处理异常情况输出一个操作步骤:切换到 半自动工作模式,再发送 脱开指令。
        • 问题三:
          • 在自动工作模式下,发送调平和碰钉之外的指令,会不会受到影响?
        • 答案:
          • 不会,在运动过程中,原则上仅接收 暂停和终止指令。
    • 软件优化
      • 界面增加末端速度设置
        • 使用到的控件有 QDoubleSpinBox, QPushButton
  • 11.22

    • 现场作业
      • 记录每组作业时间
      • 优化前后轴和左右轴速度
      • 问题:
        • 两组同时打磨,占用功率过大,导致路由器可能会因为电压不足而关闭,这样在软件上表现的现象是 碰钉过程中网络传输超时,无法控制末端
      • 解决方法
        • 硬件上将路由器和打磨的电路隔离开
        • 软件上,每一组单独打磨。
          • 想法:打磨和碰钉过程分开。
  • 11.23

    • 现场作业
      • 准备碰钉流程的备用方案:打磨一次打一组 [done]
      • 想法
        • 已经实现的新碰钉流程是两组两组交叉执行,一组分为两个打磨和两个焊枪。
        • 修改为 两组交叉执行,一组分为一个打磨和一个焊枪,一次仅有一个打磨工作
      • 软件优化
        • 自动工作过程中,禁止更换到开发者模式
        • 发送保护,按钮多次点击保护
        • 自动工作模式按钮变大
        • 舵轮旋转速度增大

2024.11.25 - 2024.12.01

  • 11.25

    • 软件交互优化
      • 碰钉–待碰钉状态颜色显示: [done]
      • 自动工作过程中,禁止切换到开发者模式
      • 增加按钮重复下发保护
      • 增加软件打包程序
  • 11.26

    • 打磨测试
    • 碰钉作业效率优化
  • 11.27

    • 上斜板作业
      • 举升目标距离 60
      • 举升最大差值 10
    • 侧板作业
      • 举升目标距离 13
      • 举升最大差值 3
    • 顶板作业
      • 举升目标距离 11
      • 举升最大差值 3
      • 走到目标大概100mm左右,固定机器人 开始作业流程
    • 顶板作业
      • 效率提升:在退出界面,可响应遥控器指令。退出时,可调整机器人 [done]
  • 11.28

    • 软件优化
      • 装卸位
      • 打包位
      • 轴限位限制解开
      • 开发者模式权限
      • 限位可配置
  • 11.29

    • 收集现场作业视频,完成 11.28日碰钉现场实验安排 文档的填写 [done]
    • 打包程序 [doing]
    • 整理软件需要优化的地方
      • 自己整理
        • 装卸位
        • 打包位
        • 轴限位限制解开
        • 开发者模式权限
        • 限位可配置
      • 桂干
        1. 开发者界需要面加一个权限密码
        2. 调节轮子朝向那需要有一个明确的方向反馈
        3. 用遥控器移动车身时微调时有明显延迟
        4. 视觉相机测量数据有延迟,有时候数据时有时无
        5. 机器人每个轴的限位,现场需要可以直接查到或者看到

2024.12.02 - 2024.12.08

  • 12.02

    • 整理视觉代码,清理死循环日志,方便调试 [done]
    • 软件优化
      • 增加参数页面,支持参数回显和修改参数
    • 周三过去,周四演示
    • 碰钉收尾
      • 实验报告
    • 装板
      • 测试
    • 汇报以效果为主
  • 12.03

    • 完成 划线-碰钉-装板试验验证手册 文档 [done]
    • 碰钉软件优化工作往后推,优先处理装板
      • 环境配置,程序可运行 [done]
      • 测试装板流程 [doing]
  • 12.04

    • 现场测试,GTT观看
    • 2024.11.26版本为验收版本
    • 增加碰钉重构版本,计划重构项目源代码,提升自己项目设计和开发能力。
      • 先重构通讯模块,提升网络编程
      • 其次重构视觉模块,学习模型后处理,GPU推理加速
      • 最后重构人机交互模块,学习Qt相关开发
    • 视觉模块
      • 增加设备配置文件
        • 存储相机编号,位置
    • 项目代码
      • 整理源代码结构 [done]
      • 解决编译时输出的告警信息,因为输出太频繁,掩盖了其他日志 [done]
  • 12.05

    • 出差
  • 12.06

    • 装板机器人流程测试
      • 贴合流程初步测试没有问题,完成流程待测试 [done]

2024.12.09 - 2024.12.15

  • 12.09

    • 装板机器人流程测试
    • 装板机器人代码优化 [doing]
  • 12.10

    • 装板机器人优化
      • 增加回零位功能 [done]
      • 增加轴测试功能 [done]
      • 现场应用熟悉装板机器人操作流程 [done]
      • 分析对边过程耗时过长的原因,是机器人走的不准还是边线检测的问题 [doing]
  • 12.11

    • 装板机器人优化
      • 针对通讯模块,删除装板不需要的功能,重构通讯组件
    • 作业效率优化
      • 分析对边过程耗时过长的原因,是机器人走的不准还是边线检测的问题 [doing]
    • 明天出差
      • 测试顶面装板流程,这次还不是验收
  • 12.12

    • 通讯模块
      • 都是客户端,同步连接,异步通信
    • 现场问题记录
      • 腰部俯仰 电机错误码 13.0
      • 测试装板新流程
  • 12.13

    • 装板机器人:
      • 优化界面卡顿问题
      • 调试摄像头参数
      • 测试装板流程
  • 12.14

    • 思考工作方向
      • 网络编程,
      • 高性能计算,
  • 12.15

    • 客户端重连怎么实现
      • 线程A:检查状态,是否已经连接。
        • 这个线程,在asio中是async_connect()的谓语
      • 线程B:发送和接收数据
        • 这个线程

2024.12.16 - 2024.12.22

  • 12.16

    • 现场出差
      • 装板作业测试
        • 对边阶段调整量过大问题复现
        • 装板流程测试
      • 通讯模块asio学习
        • 怎么知道服务端关闭了连接,从而及时执行重连
        • 客户端连接服务器
          • 根据服务端的ip和端口,创建套接字
          • 连接服务端
          • 发送数据,接收数据
        • 服务端接收客户端的连接
          • 监听端口号
          • 等待客户端发出连接请求,有请求过来,创建一个套接字,并与之关联一个工作线程,处理改连接数据的接收和发送
        • 超时机制
          • 读取数据超时
  • 12.17

    • 装板机器人
      • 支持三种作业场景,为验收做准备
      • 当前方案
        • 保存三个场景的配置文件,
        • 先测试侧板,上斜板场景是否可作业,回公司再修改上位机软件
  • 12.18

    • 装板机器人
      • 优化人机交互界面,增加三个作业场景 [done]
  • 12.19

    • 一定要搞懂asio的异步编程,重构通讯模块。
      • 支持多个客户端,同步接收和发送数据 [done]
      • 客户端,支持重连 [doing]
  • 12.20

    • asio的网络通讯异步编程
      • 客户端,支持重连[done]
    • 装板机器人
      • 优化UI界面
      • 加入tcp client
      • 待网络联调
  • 12.21

    • 江南出差 – 装板机器人
      • 视觉调试相邻板作业场景
      • 任务记录各阶段耗时,优化作业效率

2024.12.23 - 2024.12.29

  • 12.23

    • 装板流程效率优化
      • 调平阶段 *= 5
      • 对边阶段
    • 耗时主要原因
      • 工具升降速度为2mm/s
    • 解决板子未推到底的问题
      • config_ro.yaml: Lift_Distance_In_FitBoard 参数由 6.0 改为 3.0,模拟测试的效果,最终贴合举升运动的目标距离为 2mm。
      • 考虑到
        • 点激光数据会出现负值
        • 顶的太高,可能造成精度损失
  • 12.24

    • 装板优化
      • 在贴合阶段,30mm内运动,判断调整量,如果超过圆孔直径,重新计算
  • 12.25

    • 贴合流程优化
      • 确保轮廓激光和视觉数据实时性,每个运动节点增加延时 [done]
      • 界面增加自动保存图片开关 [done]
  • 12.26

    • 贴合精度损失原因分析
      • 贴合阶段,最后一段运动,工装压胶进入,检测结果观察到波动,整体机器人有波动。侧板场景和顶板场景的精度损失都主要发生在长边
    • 侧板场景作业
      • 左右精度满足要求,
      • 两个长边精度差2mm
  • 12.27

    • 装板机器人
      • 整理测试数据,形成实验报告 [done]
  • 12.28

    • 休息
  • 12.29

    • 优化个人博客
      • 增加插入图片
    • 规划
      • AI部署工程师
        • TensorRT
        • OpenVINO
      • 机器人软件工程师
        • 精通常见控制算法:MPC,DDP,DWA,TEB
        • 运动学,动力学分析推导
        • 熟悉路径规划算法:A, D
  • 12.30

    • 学习onnxruntime,复现边线检测业务
  • 12.31

    • 相机画面调大,为手工操作作准备
    • 查看装板视频,分析各个环节耗时
    • 手动操作,从举升位开始,手动走xyz,对边,贴合。
    • 增加手动对边按钮

简介

  • C++ 标准模板库(Standard Template Library, STL)是一套功能强大的C++模板类和函数的集合,它提供了一系列通用的,可复用的算法和数据结构。

  • STL的设计基于泛型编程,这意味着使用模板可以编写出独立于任何特定数据类型的代码。

  • STL分为多个组件,包括容器(Containers),迭代器(Iterators),算法(Algorithms),函数对象(Function Objects)和适配器(Adapters)等

  • 使用STL的好处

    • 代码复用: STL提供了大量通用数据和算法,可以减少重复编写代码的工作
    • 性能优化: STL中的算法和数据结构都经过了优化,以提供最佳的性能
    • 泛型编程: 使用模板,STL支持泛型编程,使得算法和数据结构可以适用于任何数据类型
    • 易于维护: STL的设计使得代码更加模板化,易于阅读和维护
  • C++标准模板库的核心包括以下重要组件

    • 容器(Containers): 容器是STL中最基本的组件之一,提供了各种数据结构,包括向量(vector),链表(list),队列(queue),栈(stack),集合(set),映射(map)等。这些容器具有不同的特性和用途,可以根据实际需求选择合适的容器
    • 算法(Algorithms): STL提供了大量的算法,用于对容器中的元素进行各种操作,包括排序,搜索,复制,移动,变换等。这些算法在使用时不需要关心容器的具体类型,只需要指定要操作的范围即可。
    • 迭代器(iterators): 迭代器用于遍历容器中的元素,允许以统一的方式访问容器中的元素,而不用关心容器的内部实现细节。STL提供了多种类型的迭代器,包括随机访问迭代器,双向迭代器,前向迭代器和输入输出迭代器等
    • 函数对象(Function Objects): 函数对象是可以像函数一样调用的对象,可以用于算法中的各种操作。STL提供了多种函数对象,包括一元函数对象 ,二元函数对象,谓词等,可以满足不同的需求
    • 适配器(Adapters): 适配器用于将一种容器或迭代器适配成另一种容器或迭代器,以满足特定的需求。STL提供了多种适配器,包括栈适配器(stack adapter),队列适配器(queue adapter)和优先队列适配器(priority queue adapter)等。
  • Containers are used to store the data

  • Algorithms are used to process the data

  • Functors are used to write custom algorithms

  • Iterators are used to navigate through the data

  • All of them are part of STL

Read more »