【LUA】转载github自用二改模版——调节音量、显示七日天气、历史剪贴板、系统信息显示

二改模版笔记

自动重新加载HS

function reloadConfig(files)doReload = falsefor _,file in pairs(files) doif file:sub(-4) == ".lua" thendoReload = trueendendif doReload thenhs.reload()end
end
myWatcher = hs.pathwatcher.new(os.getenv("HOME") .. "/.hammerspoon/", reloadConfig):start()
hs.alert.show("Config loaded")

调节音量

function changeVolume(diff)return function()local current = hs.audiodevice.defaultOutputDevice():volume()local new = math.min(100, math.max(0, math.floor(current + diff)))if new > 0 thenhs.audiodevice.defaultOutputDevice():setMuted(false)endhs.alert.closeAll(0.0)hs.alert.show("Volume " .. new .. "%", {}, 0.5)hs.audiodevice.defaultOutputDevice():setVolume(new)end
endhs.hotkey.bind({"shift","ctrl",'command'}, 'Down', changeVolume(-3))
hs.hotkey.bind({"shift","ctrl",'command'}, 'Up', changeVolume(3))

显示七日天气

local urlApi = 'http://v1.yiketianqi.com/free/api'
local menubar = hs.menubar.new()
local menuData = {}local weaEmoji = {lei = '🌩️',qing = '☀️',shachen = '😷',wu = '🌫',xue = '❄️',yu = '🌧',yujiaxue = '🌨',yun = '☁️',zhenyu = '🌧',yin = '⛅️',default = ''
}function updateMenubar()menubar:setTooltip("Weather Info")menubar:setMenu(menuData)
endfunction getWeather()hs.http.doAsyncRequest(urlApi, "GET", nil,nil, function(code, body, htable)if code ~= 200 thenprint('get weather error:'..code)returnendrawjson = hs.json.decode(body)city = rawjson.citymenuData = {}for k, v in pairs(rawjson.data) doif k == 1 thenmenubar:setTitle(weaEmoji[v.wea_img])if v.win_speed == "<3级" thentitlestr = string.format("%s  %s %s  🌡️%s-%s°C", city,weaEmoji[v.wea_img], v.wea, v.tem_night, v.tem_day)elsetitlestr = string.format("%s  %s 🌡️%s-%s°C  💨%s %s %s", city,weaEmoji[v.wea_img],v.tem_night, v.tem_day, v.win_speed,  v.win, v.wea)enditem = { title = titlestr }table.insert(menuData, item)table.insert(menuData, {title = '-'})elseif v.win_speed == "<3级" thentitlestr = string.format("%s  %s 🌡️%s-%s°C     %s",  v.date, weaEmoji[v.wea_img], v.tem_night, v.tem_day, v.wea)elsetitlestr = string.format("%s  %s 🌡️%s-%s°C  💨%s %s %s",  v.date, weaEmoji[v.wea_img],v.tem_night, v.tem_day, v.win_speed, v.win, v.wea)enditem = { title = titlestr }table.insert(menuData, item)endendupdateMenubar()end)
endmenubar:setTitle('👀')
getWeather()
updateMenubar()
hs.timer.doEvery(3000, getWeather)

剪贴板

其中设置这个为true的话,可以直接插入
local pasteOnSelect = false -- Auto-type on click

--[[From https://github.com/victorso/.hammerspoon/blob/master/tools/clipboard.luaModified by Diego Zamboni
]]---- Feel free to change those settings
local frequency = 0.8 -- Speed in seconds to check for clipboard changes. If you check too frequently, you will loose performance, if you check sparsely you will loose copies
local hist_size = 100 -- How many items to keep on history
local label_length = 70 -- How wide (in characters) the dropdown menu should be. Copies larger than this will have their label truncated and end with "…" (unicode for elipsis ...)
local honor_clearcontent = false --asmagill request. If any application clears the pasteboard, we also remove it from the history https://groups.google.com/d/msg/hammerspoon/skEeypZHOmM/Tg8QnEj_N68J
local pasteOnSelect = false -- Auto-type on click-- Don't change anything bellow this line
local jumpcut = hs.menubar.new()
jumpcut:setTooltip("Clipboard history")
local pasteboard = require("hs.pasteboard") -- http://www.hammerspoon.org/docs/hs.pasteboard.html
local settings = require("hs.settings") -- http://www.hammerspoon.org/docs/hs.settings.html
local last_change = pasteboard.changeCount() -- displays how many times the pasteboard owner has changed // Indicates a new copy has been made--Array to store the clipboard history
local clipboard_history = settings.get("so.victor.hs.jumpcut") or {} --If no history is saved on the system, create an empty historyfunction subStringUTF8(str, startIndex, endIndex)if startIndex < 0 thenstartIndex = subStringGetTotalIndex(str) + startIndex + 1endif endIndex ~= nil and endIndex < 0 thenendIndex = subStringGetTotalIndex(str) + endIndex + 1endif endIndex == nil then return string.sub(str, subStringGetTrueIndex(str, startIndex))elsereturn string.sub(str, subStringGetTrueIndex(str, startIndex), subStringGetTrueIndex(str, endIndex + 1) - 1)end
end--返回当前截取字符串正确下标
function subStringGetTrueIndex(str, index)local curIndex = 0local i = 1local lastCount = 1repeat lastCount = subStringGetByteCount(str, i)i = i + lastCountcurIndex = curIndex + 1until(curIndex >= index)return i - lastCount
end--返回当前字符实际占用的字符数
function subStringGetByteCount(str, index)local curByte = string.byte(str, index)local byteCount = 1if curByte == nil thenbyteCount = 0elseif curByte > 0 and curByte <= 127 thenbyteCount = 1elseif curByte>=192 and curByte<=223 thenbyteCount = 2elseif curByte>=224 and curByte<=239 thenbyteCount = 3elseif curByte>=240 and curByte<=247 thenbyteCount = 4endreturn byteCount
end-- Append a history counter to the menu
function setTitle()if (#clipboard_history == 0) thenjumpcut:setTitle("✂") -- Unicode magicelsejumpcut:setTitle("✂") -- Unicode magic--      jumpcut:setTitle("✂ ("..#clipboard_history..")") -- updates the menu counterend
endfunction putOnPaste(string,key)if (pasteOnSelect) thenhs.eventtap.keyStrokes(string)pasteboard.setContents(string)last_change = pasteboard.changeCount()elseif (key.alt == true) then -- If the option/alt key is active when clicking on the menu, perform a "direct paste", without changing the clipboardhs.eventtap.keyStrokes(string) -- Defeating paste blocking http://www.hammerspoon.org/go/#pasteblockelsepasteboard.setContents(string)last_change = pasteboard.changeCount() -- Updates last_change to prevent item duplication when putting on pasteendend
end-- Clears the clipboard and history
function clearAll()pasteboard.clearContents()clipboard_history = {}settings.set("so.victor.hs.jumpcut",clipboard_history)now = pasteboard.changeCount()setTitle()
end-- Clears the last added to the history
function clearLastItem()table.remove(clipboard_history,#clipboard_history)settings.set("so.victor.hs.jumpcut",clipboard_history)now = pasteboard.changeCount()setTitle()
endfunction pasteboardToClipboard(item)-- Loop to enforce limit on qty of elements in history. Removes the oldest itemswhile (#clipboard_history >= hist_size) dotable.remove(clipboard_history,1)endtable.insert(clipboard_history, item)settings.set("so.victor.hs.jumpcut",clipboard_history) -- updates the saved historysetTitle() -- updates the menu counter
end-- Dynamic menu by cmsj https://github.com/Hammerspoon/hammerspoon/issues/61#issuecomment-64826257
populateMenu = function(key)setTitle() -- Update the counter every time the menu is refreshedmenuData = {}if (#clipboard_history == 0) thentable.insert(menuData, {title="None", disabled = true}) -- If the history is empty, display "None"elsefor k,v in pairs(clipboard_history) doif (string.len(v) > label_length) thentable.insert(menuData,1, {title=subStringUTF8(v,0,label_length).."…", fn = function() putOnPaste(v,key) end }) -- Truncate long stringselsetable.insert(menuData,1, {title=v, fn = function() putOnPaste(v,key) end })end -- end if elseend-- end forend-- end if else-- footertable.insert(menuData, {title="-"})table.insert(menuData, {title="Clear All", fn = function() clearAll() end })if (key.alt == true or pasteOnSelect) thentable.insert(menuData, {title="Direct Paste Mode ✍", disabled=true})endreturn menuData
end-- If the pasteboard owner has changed, we add the current item to our history and update the counter.
function storeCopy()now = pasteboard.changeCount()if (now > last_change) thencurrent_clipboard = pasteboard.getContents()-- asmagill requested this feature. It prevents the history from keeping items removed by password managersif (current_clipboard == nil and honor_clearcontent) thenclearLastItem()elsepasteboardToClipboard(current_clipboard)endlast_change = nowend
end--Checks for changes on the pasteboard. Is it possible to replace with eventtap?
timer = hs.timer.new(frequency, storeCopy)
timer:start()setTitle() --Avoid wrong title if the user already has something on his saved history
jumpcut:setMenu(populateMenu)hs.hotkey.bind({"cmd", "shift"}, "v", function() jumpcut:popupMenu(hs.mouse.getAbsolutePosition()) end)

系统信息显示

--- 显示系统信息
--- 可显示CPU\内存\硬盘\网络等实时信息
--- Created by sugood(https://github.com/sugood).
--- DateTime: 2022/01/14 22:00
---local menubaritem = hs.menubar.new()
local menuData = {}-- ipv4Interface ipv6 Interface
local interface = hs.network.primaryInterfaces()-- 该对象用于存储全局变量,避免每次获取速度都创建新的局部变量
local obj = {}function init()if interface thenlocal interface_detail = hs.network.interfaceDetails(interface)if interface_detail.IPv4 thenlocal ipv4 = interface_detail.IPv4.Addresses[1]table.insert(menuData, {title = "IPv4:" .. ipv4,tooltip = "Copy Ipv4 to clipboard",fn = function()hs.pasteboard.setContents(ipv4)end})endlocal mac = hs.execute('ifconfig ' .. interface .. ' | grep ether | awk \'{print $2}\'')table.insert(menuData, {title = 'MAC:' .. mac,tooltip = 'Copy MAC to clipboard',fn = function()hs.pasteboard.setContents(mac)end})obj.last_down = hs.execute('netstat -ibn | grep -e ' .. interface .. ' -m 1 | awk \'{print $7}\'')obj.last_up = hs.execute('netstat -ibn | grep -e ' .. interface .. ' -m 1 | awk \'{print $10}\'')elseobj.last_down =  0obj.last_down =  0endlocal date=os.date("%Y-%m-%d %a");table.insert(menuData, {title = 'Date: '..date,tooltip = 'Copy Now DateTime',fn = function()hs.pasteboard.setContents(os.date("%Y-%m-%d %H:%M:%S"))end})table.insert(menuData, {title = '打开:监  视  器    (⇧⌃A)',tooltip = 'Show Activity Monitor',fn = function()bindActivityMonitorKey()end})table.insert(menuData, {title = '打开:磁盘工具    (⇧⌃D)',tooltip = 'Show Disk Utility',fn = function()bindDiskKey()end})table.insert(menuData, {title = '打开:系统日历    (⇧⌃C)',tooltip = 'Show calendar',fn = function()bindCalendarKey()end})menubaritem:setMenu(menuData)
endfunction scan()if interface thenobj.current_down = hs.execute('netstat -ibn | grep -e ' .. interface .. ' -m 1 | awk \'{print $7}\'')obj.current_up = hs.execute('netstat -ibn | grep -e ' .. interface .. ' -m 1 | awk \'{print $10}\'')elseobj.current_down  = 0obj.current_up = 0endobj.cpu_used = getCpu()obj.disk_used = getRootVolumes()obj.mem_used = getVmStats()obj.down_bytes = obj.current_down - obj.last_downobj.up_bytes = obj.current_up - obj.last_upobj.down_speed = format_speed(obj.down_bytes)obj.up_speed = format_speed(obj.up_bytes)obj.display_text = hs.styledtext.new('▲ ' .. obj.up_speed .. '\n'..'▼ ' .. obj.down_speed , {font={size=9}, color={hex='#FFFFFF'}, paragraphStyle={alignment="left", maximumLineHeight=18}})obj.display_disk_text = hs.styledtext.new(obj.disk_used ..'\n'.. 'SSD ' , {font={size=9}, color={hex='#FFFFFF'}, paragraphStyle={alignment="left", maximumLineHeight=18}})obj.display_mem_text = hs.styledtext.new(obj.mem_used ..'\n'.. 'MEM ' , {font={size=9}, color={hex='#FFFFFF'}, paragraphStyle={alignment="left", maximumLineHeight=18}})obj.display_cpu_text = hs.styledtext.new(obj.cpu_used ..'\n'.. 'CPU ' , {font={size=9}, color={hex='#FFFFFF'}, paragraphStyle={alignment="left", maximumLineHeight=18}})obj.last_down = obj.current_downobj.last_up = obj.current_uplocal canvas = hs.canvas.new{x = 0, y = 0, h = 24, w = 30+30+30+60}-- canvas[1] = {type = 'text', text = obj.display_text}canvas:appendElements({type = "text",text = obj.display_cpu_text,-- withShadow = true,trackMouseEnterExit = true,},{type = "text",text = obj.display_disk_text,-- withShadow = true,trackMouseEnterExit = true,frame = { x = 30, y = "0", h = "1", w = "1", }},{type = "text",text = obj.display_mem_text,-- withShadow = true,trackMouseEnterExit = true,frame = { x = 60, y = "0", h = "1", w = "1", }},{type = "text",text = obj.display_text,-- withShadow = true,trackMouseEnterExit = true,frame = { x = 90, y = "0", h = "1", w = "1", }})menubaritem:setIcon(canvas:imageFromCanvas())canvas:delete()canvas = nil
endfunction format_speed(bytes)-- 单位 Byte/sif bytes < 1024 thenreturn string.format('%6.0f', bytes) .. ' B/s'else-- 单位 KB/sif bytes < 1048576 then-- 因为是每两秒刷新一次,所以要除以 (1024 * 2)return string.format('%6.1f', bytes / 2048) .. ' KB/s'-- 单位 MB/selse-- 除以 (1024 * 1024 * 2)return string.format('%6.1f', bytes / 2097152) .. ' MB/s'endend
endfunction getCpu()local data = hs.host.cpuUsage()local cpu = (data["overall"]["active"])return formatPercent(cpu)
endfunction getVmStats()local vmStats = hs.host.vmStat()-- --1024^2-- local megDiv = 1048576-- local megMulti = vmStats.pageSize / megDiv-- local totalMegs = vmStats.memSize / megDiv  --总内存-- local megsCached = vmStats.fileBackedPages * megMulti   --缓存内存-- local freeMegs = vmStats.pagesFree * megMulti   --空闲内存-- --第一种方法使用 APP内存+联动内存+被压缩内存 = 已使用内存-- --local megsUsed =  vmStats.pagesWiredDown * megMulti -- 联动内存-- --megsUsed = megsUsed + vmStats.pagesUsedByVMCompressor * megMulti -- 被压缩内存-- --megsUsed = megsUsed + (vmStats.pagesActive +vmStats.pagesSpeculative)* megMulti  -- APP内存-- --第二种方法使用 总内存-缓存内存-空闲内存 = 已使用内存-- local megsUsed = totalMegs - megsCached - freeMegs--第三种方法,由于部分设备pageSize获取不正确,所以只能通过已使用页数+缓存页数+空闲页数计算总页数local megsUsed =  vmStats.pagesWiredDown -- 联动内存megsUsed = megsUsed + vmStats.pagesUsedByVMCompressor -- 被压缩内存megsUsed = megsUsed + vmStats.pagesActive +vmStats.pagesSpeculative -- APP内存local megsCached = vmStats.fileBackedPages   --缓存内存local freeMegs = vmStats.pagesFree   --空闲内存local totalMegs = megsUsed + megsCached + freeMegslocal usedMem = megsUsed/totalMegs * 100return formatPercent(usedMem)
endfunction getRootVolumes()local vols = hs.fs.volume.allVolumes()for key, vol in pairs(vols) dolocal size = vol.NSURLVolumeTotalCapacityKeylocal free = vol.NSURLVolumeAvailableCapacityKeylocal usedSSD = (1-free/size) * 100if ( string.find(vol.NSURLVolumeNameKey,'Macintosh') ~= nil) thenreturn formatPercent(usedSSD)endendreturn ' 0%'
endfunction formatPercent(percent)if ( percent <= 0 ) thenreturn "  1%"elseif ( percent < 10 ) thenreturn "  " .. string.format("%.f", percent) .. "%"elseif  (percent > 99 )thenreturn "100%"elsereturn string.format("%.f", percent) .. "%"end
endlocal setSysInfo= function()--    if config ~=nil and config[1].showSysInfo ~= 'on' thenif 1 thenif(menuBarItem ~= nil and menuBarItem:isInMenuBar() == false) thenreturnendif (menuBarItem == nil) thenprint("设置状态栏:系统信息")menuBarItem= hs.menubar.new()elseif (menuBarItem:isInMenuBar() == false) thenmenuBarItem:delete()menuBarItem= hs.menubar.new()endinit()scan()if obj.timer thenobj.timer:stop()obj.timer = nilend-- 三秒刷新一次obj.timer = hs.timer.doEvery(3, scan):start()end
endfunction initData()setSysInfo()--监听系统信息开关的状态,判断是否要重置hs.timer.doEvery(1, setSysInfo)
end-- 初始化
initData()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/655554.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

测试ASP.NET Core项目调用EasyCaching的基本用法(InMemory)

EasyCaching属于开源缓存库&#xff0c;支持基本缓存方式及高级缓存用法&#xff0c;提高用户操作缓存的效率。EasyCaching支持的缓存方式包括以下类型&#xff0c;本文学习最基础的InMemory方式的基本用法。   EasyCaching.InMemory包属于基于内存的缓存库&#xff0c;使用的…

Jetson JetPack6.0 DP L4T 36.2

JetPack 6是有史以来最大的升级。 它不仅带来了更新的内核和更新的Ubuntu根文件系统&#xff0c;而且还包括以前从未在Jetson上提供的新功能。J etPack 6首次提供了运行任何Linux内核的灵活性&#xff0c;并提供了Jetson生态系统合作伙伴基于Linux的发行版的更广泛选择。 阅…

读取appsettings.json属性

1、定义对应读取类ReadConfig. 2、对应类中函数 private static IConfigurationRoot builder; static ConfigHelper() { builder new ConfigurationBuilder() .AddInMemoryCollection() .Set…

最后50个CC龙年红包封面,免费速领!还有更多......高中生也卷起Steam来了

微信视频号之前是送了我3张新年红包封面&#xff0c;一共是150个&#xff0c;但不太会操作浪费了100个&#xff0c;只能我自己用来送老铁了。 晓衡又做了一条 Cocos 小可爱 CC 封面红包&#xff0c;特别适合送女生或给小朋友们&#xff0c;点击视频领取&#xff01;还好微信又送…

Docker 搭建MySQL主从复制-读写分离

一. 介绍 MySQL主从复制是一种常用的数据库高可用性解决方案&#xff0c;通过在主数据库上记录的数据变更&#xff0c;同步到一个或多个从数据库&#xff0c;实现数据的冗余备份和读写分离。在Docker环境下搭建MySQL主从复制和读写分离&#xff0c;不仅方便管理&#xff0c;还…

管理类联考-复试-英语口试

文章目录 主要内容注意事项常用短语常见话题模版在职生模板一在职生模板二 模板Sample lSample 2Sample 3Sample 4Sample 5Sample 6Sample 7Sample 8-简介版自我介绍 主要内容 1、简单问候 向老师们致以简单的问候&#xff0c;调整状态。 2、个人信息 姓名、年龄、毕业院校、…

为什么要用云手机养tiktok账号

在拓展海外电商市场的过程中&#xff0c;许多用户选择采用tiktok短视频平台引流的策略&#xff0c;以提升在电商平台上的流量&#xff0c;吸引更多消费者。而要进行tiktok引流&#xff0c;养号是必不可少的一个环节。tiktok云手机成为实现国内跨境养号的一种有效方式&#xff0…

【Docker】WSL(Windows Subsystem for Linux)常见命令解释说明以及简单使用

欢迎来到《小5讲堂》&#xff0c;大家好&#xff0c;我是全栈小5。 这是《Docker容器》序列文章&#xff0c;每篇文章将以博主理解的角度展开讲解&#xff0c; 特别是针对知识点的概念进行叙说&#xff0c;大部分文章将会对这些概念进行实际例子验证&#xff0c;以此达到加深对…

【Spring实战】32 Spring Boot3 集成 Nacos 服务注册中心 并在 Gateway 网关中应用

文章目录 1. 定义2. 背景3. 功能和特性4. 下载安装5. 服务启动6. 使用示例1&#xff09;服务提供者2&#xff09;服务消费者3&#xff09;测试 7. 代码参考结语 1. 定义 Nacos 是 Dynamic Naming and Configuration Service 的首字母简称&#xff0c;一个更易于构建云原生应用…

Git怎样用?(下载到本地,和在本地初始化)

全局设置&#xff1a; 点击第二个 输入&#xff1a; 例如&#xff1b;邮箱是随意地 git config --global user.name "名字" git config --global user.email "邮箱" 获取git仓库 本地初始化&#xff1a; 创建仓库 右键第二个 输入 git init 克隆&#…

prism 10 for Mac v10.1.1.270激活版 医学绘图分析软件

GraphPad Prism 10 for Mac是一款专为科研工作者和数据分析师设计的绘图和数据可视化软件。以下是该软件的一些主要功能&#xff1a; 软件下载&#xff1a;prism 10 for Mac v10.1.1.270激活版 数据整理和导入&#xff1a;GraphPad Prism 10支持从多种数据源导入数据&#xff0…

HarmonyOS模拟器启动失败,电脑蓝屏解决办法

1、在Tool->Device Manager管理界面中&#xff0c;通过Wipe User Data清理模拟器用户数据&#xff0c;然后重启模拟器&#xff1b;如果该方法无效&#xff0c;需要Delete删除已创建的Local Emulater。 2、在Tool->SDK Manager管理界面的PlatForm选项卡中&#xff0c;取消…

导出excel功能,前端的解决方案

import { utils, writeFileXLSX } from xlsx // 导出excel async exportToExcel() {// 获取要导出的业务数据&#xff08;这里的接口自己改成实际使用的接口&#xff09;const res await getRuleListAPI(this.params)// 表头英文字段key&#xff08;这里的数据改成接口返回的实…

Bitbucket第一次代码仓库创建/提交/创建新分支/合并分支/忽略ignore

1. 首先要在bitbucket上创建一个项目&#xff0c;这个我没有权限创建&#xff0c;是找的管理员创建的。 管理员创建之后&#xff0c;这个项目给了我权限&#xff0c;我就可以创建我的代码仓库了。 2. 点击这个Projects下的具体项目名字&#xff0c;就会进入这样一个页面&#…

TensorFlow2实战-系列教程12:RNN文本分类4

&#x1f9e1;&#x1f49b;&#x1f49a;TensorFlow2实战-系列教程 总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在Jupyter Notebook中进行 本篇文章配套的代码资源已经上传 8、压缩版本网络模型 class Model(tf.keras.Model):def __init__(self, params):supe…

选矿二厂电气系统维管工作项目招标公告

选矿二厂电气系统维管工作项目招标公告 (招标编号&#xff1a;JDCRY-ZB2024-05) 项目所在地区&#xff1a;河南省,洛阳市,汝阳县 一、招标条件 本选矿二厂电气系统维管工作项目已由项目审批/核准/备案机关批准&#xff0c;项目资金来源为自筹资金438万元&#xff0c;招标人…

QT C++语言格式化输出wchar_t * 中文乱码

在 Qt 中&#xff0c;如果你使用 wprintf 或 wcout 进行宽字符输出&#xff0c;而且你的字符串包含中文字符&#xff0c;确保使用 Unicode 字符集&#xff0c;并将字符串编码为 UTF-16。此外&#xff0c;确保你的输出流和终端都能正确地处理宽字符。 下面是一个简单的例子&…

[GN] 设计模式—— 创建型模式

文章目录 创建型模式单例模式 -- 确保对象唯一性饿汉式懒汉式优缺点使用场景 简单工厂模式例子&#xff1a;优化优缺点适用场景 工厂方法模式--多态工厂的实现例子优缺点适用场景 创建型模式 单例模式 – 确保对象唯一性 用TaskManager类。通过以下三步进行重构 为了确保Ta…

[足式机器人]Part3 机构运动学与动力学分析与建模 Ch01-2 完整定常系统——杆组RRR

本文仅供学习使用,总结很多本现有讲述运动学或动力学书籍后的总结,从矢量的角度进行分析,方法比较传统,但更易理解,并且现有的看似抽象方法,两者本质上并无不同。 2024年底本人学位论文发表后方可摘抄 若有帮助请引用 本文参考: 《空间机构的分析与综合(上册)》-张启先…

redis-4 集群

应用场景 为什么需要redis集群&#xff1f; 当主备复制场景&#xff0c;无法满足主机的单点故障时&#xff0c;需要引入集群配置。 一般数据库要处理的读请求远大于写请求 &#xff0c;针对这种情况&#xff0c;我们优化数据库可以采用读写分离的策略。我们可以部 署一台主服…