panda3d 渲染

目录

安装

设置渲染宽高:

渲染3d


安装

pip install Panda3D

设置渲染宽高:

import panda3d.core as pdmargin = 100
screen = Tk().winfo_screenwidth() - margin, Tk().winfo_screenheight() - margin
width, height = (screen[0], int(screen[0] / 1.8)) if screen[0] / screen[1] < 1.8 else (int(screen[1] * 1.8), screen[1])
width,height=1200,800
pd.loadPrcFileData("", "win-origin {} {}".format((screen[0] + margin - width) // 2, (screen[1] + margin - height) // 2))
pd.loadPrcFileData("", "win-size {} {}".format(width, height))
pd.loadPrcFileData("", "win-fixed-size 1")

渲染3d

UnderPressure/visualization.py at main · InterDigitalInc/UnderPressure · GitHub

"""Copyright (c) 2022, InterDigital R&D France. All rights reserved. This sourcecode is made available under the license found in the LICENSE.txt at the rootdirectory of the repository.
"""# UnderPressure
import anim, util
from data import FRAMERATE, TOPOLOGY, Forces# Python
import math, time
from pathlib import Path
from tkinter import Tk# PyTorch
import torch# Panda3D
import panda3d.core as pd
from direct.showbase.ShowBase import ShowBase
from direct.task import Task
from direct.gui.DirectGui import DGG, DirectButton, DirectLabel, DirectSliderdef rotate(pts, axis, angle):axis = torch.nn.functional.normalize(axis, p=2, dim=-1)rmat = util.so3.to_SO3(angle * axis)return torch.einsum("ij,...j->...i", rmat, pts)class Geo:@classmethoddef xy2xyz(cls, tensor, z=0.0, dim=-1):													# [...] x 2 x [...]assert tensor.shape[dim] == 2x, y = tensor.unbind(dim)															# [...] x	 [...]return torch.stack([x, y, torch.full_like(x, z)], dim)								# [...] x 3 x [...]class GeomBuilder:def __init__(self, name, color=None):self.name = nameself.vdata = pd.GeomVertexData(name, pd.GeomVertexFormat.getV3n3c4(), pd.Geom.UHStatic)self.vertexWriter = pd.GeomVertexWriter(self.vdata, "vertex")self.normalWriter = pd.GeomVertexWriter(self.vdata, "normal")self.colorWriter = pd.GeomVertexWriter(self.vdata, "color")self.triangles = pd.GeomTriangles(pd.Geom.UHStatic)self.currentRow = 0self.color = colordef _vertex(self, point, normal, prim=None, color=None):color = color or self.color or [1, 1, 1, 1]self.vertexWriter.addData3(*point)self.normalWriter.addData3(*normal)self.colorWriter.addData4(color[0], color[1], color[2], color[3])if prim is not None:prim.addVertex(self.currentRow)self.currentRow += 1def triangle(self, p1, p2, p3, color=None, normal=None):if normal is None:normal = (p2 - p1).cross(p3 - p1).normalized()self._vertex(p1, normal, self.triangles, color)self._vertex(p2, normal, self.triangles, color)self._vertex(p3, normal, self.triangles, color)self.triangles.closePrimitive()def polygon(self, pts, color=None):triangulator = pd.Triangulator3()for pt in pts:triangulator.addPolygonVertex(triangulator.addVertex(*pt))triangulator.triangulate()for i in range(triangulator.getNumTriangles()):self.triangle(triangulator.getVertex(triangulator.getTriangleV0(i)),triangulator.getVertex(triangulator.getTriangleV1(i)),triangulator.getVertex(triangulator.getTriangleV2(i)),color=color)def thick_polygon(self, pts, tickness, color=None, face_color=None, edge_color=None):pts = torch.as_tensor(pts)bottom, top = pts, pts + torch.as_tensor([0, 0, tickness])self.polygon(top, face_color or color)self.polygon(bottom, face_color or color)for i in range(0, top.shape[0]):j = (i + 1) % top.shape[0]self.polygon([top[i], top[j], bottom[j], bottom[i]], edge_color or color)def cylinder(self, p1, p2, radius, n=24, color=None):p1, p2 = torch.as_tensor(p1), torch.as_tensor(p2)axis = torch.nn.functional.normalize(p2 - p1, p=2, dim=-1)					# 3ex = torch.as_tensor([1.0, 0.0, 0.0])if (axis != ex).any():rvec = radius * torch.nn.functional.normalize(ex.cross(axis), p=2, dim=-1)else:rvec = torch.as_tensor([0.0, radius, 0.0])for i in range(n):self.triangle(p1 + rotate(rvec, axis, i / n * math.tau),p2 + rotate(rvec, axis, (i + 0.5) / n * math.tau),p2 + rotate(rvec, axis, (i - 0.5) / n * math.tau),color=color,normal=rotate(rvec, axis, i / n * math.tau),)self.triangle(p2 + rotate(rvec, axis, (i + 0.5) / n * math.tau),p1 + rotate(rvec, axis, (i + 1) / n * math.tau),p1 + rotate(rvec, axis, i / n * math.tau),color=color,normal=rotate(rvec, axis, (i + 0.5) / n * math.tau),)def cube(self, center, side, color=None):return self.box(center, [side, side, side], color=color)def box(self, center, sides, color=None):center = torch.as_tensor(center)sx, sy, sz = sides[0] / 2, sides[1] / 2, sides[2] / 2vertices = torch.stack([center + torch.as_tensor([-sx, -sy, -sz]),center + torch.as_tensor([-sx, sy, -sz]),center + torch.as_tensor([-sx, sy, sz]),center + torch.as_tensor([-sx, -sy, sz]),center + torch.as_tensor([sx, -sy, -sz]),center + torch.as_tensor([sx, sy, -sz]),center + torch.as_tensor([sx, sy, sz]),center + torch.as_tensor([sx, -sy, sz]),])self.polygon(vertices[[0, 1, 2, 3]], color)self.polygon(vertices[[0, 4, 5, 1]], color)self.polygon(vertices[[1, 5, 6, 2]], color)self.polygon(vertices[[2, 6, 7, 3]], color)self.polygon(vertices[[3, 7, 4, 0]], color)self.polygon(vertices[[7, 6, 5, 4]], color)def build(self):geom = pd.Geom(self.vdata)geom.addPrimitive(self.triangles)node = pd.GeomNode(self.name)node.addGeom(geom)return nodeclass AnimationLoop:def __init__(self, length: int, fps: float, start: bool = True):self._length, self._fps = int(length), float(fps)self._time, self._frame = 0.0, 0.0self._stop, self._running = False, bool(start)self.functions = []@propertydef length(self) -> int:return self._length@length.setterdef length(self, length: int):self._length = int(length)def __len__(self) -> int:return self.length@propertydef fps(self) -> float:return self._fps@fps.setterdef fps(self, value: float):self._fps = float(value)@propertydef frame(self) -> float:return self._frame % self.length@propertydef running(self) -> bool:return self._runningdef reset(self):self._time = 0.0self._frame = 0.0def pause(self):self._running = Falsedef unpause(self):self._running = Truedef stop(self):self._stop = Truedef bind(self, fn):self.functions.append(fn)def unbind(self, fn):self.functions.remove(fn)def __call__(self, state):if self._stop:return Task.doneif self._running:self._frame += (state.time - self._time) * self.fpsfor fn in self.functions:fn(self.frame)self._frame %= self.lengthself._time = state.timereturn Task.contclass Animatable:def __init__(self, loop: AnimationLoop):self.loop = loop@propertydef loop(self):return self._loop@loop.setterdef loop(self, loop: AnimationLoop):del self.loopassert isinstance(loop, AnimationLoop)self._loop = loopself._loop.bind(self.update)@loop.deleterdef loop(self):if hasattr(self, "_loop"):self._loop.unbind(self.update)del self._loop@propertydef nframes(self):return len(self.loop)def update(self, frame: int):prev_frame, next_frame = int(math.floor(frame)), min(int(math.ceil(frame)), self.nframes-1)dframe = frame - prev_frameself.__update__(frame, prev_frame, next_frame, dframe)def __update__(self, frame: int, prev_frame: int, next_frame: int, dframe: float):raise NotImplementedError()class Ground(Animatable):DEFAULT_COLOR1 = 3 * (0.4, ) + (1.0, )DEFAULT_COLOR2 = 3 * (0.6, ) + (1.0, )def __init__(self, parent, grid, size, origin=(0, 0), color1=DEFAULT_COLOR1, color2=DEFAULT_COLOR2, loop=None, trajectory=None):grid, size = torch.as_tensor(grid).int(), torch.as_tensor(size)origin = torch.as_tensor(origin)cell = size / gridbuilder = GeomBuilder("ground")for x in range(grid[0]):for y in range(grid[1]):vertices = origin - 0.5*size + torch.stack([torch.as_tensor([x, y]) * cell,torch.as_tensor([x, y+1]) * cell,torch.as_tensor([x+1, y+1]) * cell,torch.as_tensor([x+1, y]) * cell,])color = color1 if x%2 == y%2 else color2builder.polygon(Geo.xy2xyz(vertices), color)self._node = parent.attachNewNode(builder.build())if loop is not None:super().__init__(loop)if trajectory is not None:self.trajectory = trajectory@propertydef trajectory(self):return self._trajectory.clone()@trajectory.setterdef trajectory(self, trajectory):self._trajectory = trajectory.clone()def __update__(self, frame: int, prev_frame: int, next_frame: int, dframe: float):position = torch.lerp(*self.trajectory[[prev_frame, next_frame]], dframe)self._node.setPos(*position.tolist())class Insole(Animatable):# geometryINSOLE_VERTICES = torch.load(Path(__file__).parent / "geo_insoles.pth")INSOLE_VERTICES_BBOX = torch.stack([INSOLE_VERTICES.amin(dim=0), INSOLE_VERTICES.amax(dim=0)])INSOLE_VERTICES_LENGTH = (INSOLE_VERTICES_BBOX[1, 1] - INSOLE_VERTICES_BBOX[0, 1])INSOLE_VERTICES_CENTER = 0.5 * (INSOLE_VERTICES_BBOX[0] + INSOLE_VERTICES_BBOX[1])CELLS_VERTICES = torch.load(Path(__file__).parent / "geo_insole_cells.pth")# colorsINSOLE_COLOR = (0.2, 0.2, 0.2, 1.0)TOE_COLOR = (150/255, 48/255, 48/255, 1.0)ARCH_COLOR = (0.5, 0.5, 0.5, 1.0)HEEL_COLOR = (48/255, 84/255, 150/255, 1.0)def __init__(self, parent, side, origin, length, angle, zscale=0.025, loop=None, forces=None):self._values = torch.zeros(16)self._side = sideself.__init_geometry__(parent, side, origin, length, angle)self._zscale = float(zscale)if loop is not None:super().__init__(loop)if forces is not None:self.forces = forces@classmethoddef left(cls, parent, *args, **kwargs):return cls(parent, "left", *args, **kwargs)@classmethoddef right(cls, parent, *args, **kwargs):return cls(parent, "right", *args, **kwargs)def is_left(self) -> bool:return self._side == "left"def is_right(self) -> bool:return self._side == "right"def __init_geometry__(self, parent, side, origin, length, angle):self._origin, length = torch.as_tensor(origin), torch.as_tensor(length)angle = (180 + torch.as_tensor(angle)) / 180 * math.piside = {"right": 1, "left": -1}[side]# prepare global transformtransform_mat = torch.as_tensor([[angle.cos(), -angle.sin()], [angle.sin(), angle.cos()]]) # rotationtransform_mat = torch.matmul(transform_mat, (length / self.INSOLE_VERTICES_LENGTH).expand(2).diag()) # scaletransform_mat = torch.matmul(transform_mat, torch.as_tensor([side, 1.0]).diag()) # lefttransform = lambda pts: Geo.xy2xyz(torch.einsum("ij,nj->ni", transform_mat, pts.clone() - self.INSOLE_VERTICES_CENTER))self._base_tickness = 0.002# insolebuilders = {}insole_vertices = transform(self.INSOLE_VERTICES)if side == -1:insole_vertices = insole_vertices.flip(0)builders["insole"] = GeomBuilder("insole")builders["insole"].thick_polygon(self._origin + insole_vertices, tickness=self._base_tickness,face_color=self.INSOLE_COLOR, edge_color=self.INSOLE_COLOR)# cellsfor i, cell_vertices in enumerate(self.CELLS_VERTICES):cell_vertices = transform(cell_vertices)if side == -1:cell_vertices = cell_vertices.flip(0)cell_name = "cell{}".format(i)cell_face_color = self.TOE_COLOR if i in Forces.FRONT_CELLS else self.HEEL_COLOR if i in Forces.BACK_CELLS else self.ARCH_COLORbuilders[cell_name] = GeomBuilder(cell_name)builders[cell_name].thick_polygon(cell_vertices, tickness=1.0,face_color=cell_face_color, edge_color=cell_face_color)self._nodes = {key: parent.attachNewNode(builder.build()) for key, builder in builders.items()}		cells_origin = self._origin + torch.as_tensor([0.0, 0.0, self._base_tickness])for i in range(len(self.CELLS_VERTICES)):		self._nodes["cell{}".format(i)].setPos(*cells_origin.tolist())def __getitem__(self, index):return self._values.__getitem__(index)def __setitem__(self, index, value):self._values.__setitem__(index, value)for i in range(16):z = self._zscale * self._values[i].item() + 1e-5self._nodes["cell{}".format(i)].setSz(z)@propertydef forces(self):return self._forces.clone()@forces.setterdef forces(self, forces):self._forces = forces.clone()def __update__(self, frame: int, prev_frame: int, next_frame: int, dframe: float):self[:] = torch.lerp(*self.forces[[prev_frame, next_frame]], dframe)		class InsolesPair:def __init__(self, left, right, loop=None, forces=None):self.left, self.right = left, rightif loop is not None:self.left.loop = loopself.right.loop = loopif forces is not None:self.forces = forces@propertydef left(self):return self._left@left.setterdef left(self, left):assert isinstance(left, Insole) and left.is_left()self._left = left@propertydef right(self):return self._right@right.setterdef right(self, right):assert isinstance(right, Insole) and right.is_right()self._right = rightdef __setitem__(self, index, value):values = self[:]values.__setitem__(index, value)self.left[:] = values[0]self.right[:] = values[1]def __getitem__(self, index):return torch.stack([self.left[:], self.right[:]]).__getitem__(index)@propertydef forces(self):return self.left.forces, self.right.forces@forces.setterdef forces(self, forces):self.left.forces = forces[0]self.right.forces = forces[1]def update(self, frame):self.left.update(frame)self.right.update(frame)class Skeleton(Animatable):def __init__(self, parent, skeleton, loop=None, angles=None, trajectory=None, label=""):self._skeleton = skeletonself._joints = []for joint in TOPOLOGY:node = GeomBuilder(joint)node.cube((0, 0, 0), side=0.05, color=[0.2, 0.2, 0.2, 0.0])self._joints.append(parent.attachNewNode(node.build()))if loop is not None:super().__init__(loop)if angles is not None:self.angles = anglesif trajectory is not None:self.trajectory = trajectory	if label:self._label = pd.TextNode(label)self._label.setText(label)self._label.setAlign(pd.TextNode.ACenter)self._label = parent.attachNewNode(self._label)self._label.setScale(0.1)self._label.setPos(0.0, 0.0, 1.8)@propertydef angles(self):return self._angles.clone()@angles.setterdef angles(self, angles):self._angles = angles.clone()@propertydef trajectory(self):return self._trajectory.clone()@trajectory.setterdef trajectory(self, trajectory):self._trajectory = trajectory.clone()self._label_traj = util.gma(self.trajectory, size=50, std=50/3, dim=0)def __update__(self, frame: int, prev_frame: int, next_frame: int, dframe: float):angles = util.SU2.slerp(*self.angles[[prev_frame, next_frame]], dframe)positions = anim.FK(angles, self._skeleton, 0, TOPOLOGY)if hasattr(self, "_trajectory"):positions += torch.lerp(*self.trajectory[[prev_frame, next_frame]], dframe)		if hasattr(self, "_label") and hasattr(self, "_label_traj"):self._label.setPos(*torch.lerp(*self._label_traj[[prev_frame, next_frame]], dframe)[:2].tolist(), 1.8)				for j, joint in enumerate(self._joints):joint.setQuat(pd.LQuaternion(*angles[j].tolist()))joint.setPos(*positions[j].tolist())class MocapAndvGRFsApp(ShowBase):def __init__(self, motions: list, vGRFs: list = [], motion_labels=None, vGRF_labels=None):motion_labels = [None for _ in motions] if motion_labels is None else motion_labelsvGRF_labels = [None for _ in vGRFs] if vGRF_labels is None else vGRF_labelsmargin = 100screen = Tk().winfo_screenwidth() - margin, Tk().winfo_screenheight() - marginwidth, height = (screen[0], int(screen[0] / 1.8)) if screen[0] / screen[1] < 1.8 else (int(screen[1] * 1.8), screen[1])width,height=1200,800pd.loadPrcFileData("", "win-origin {} {}".format((screen[0] + margin - width) // 2, (screen[1] + margin - height) // 2))pd.loadPrcFileData("", "win-size {} {}".format(width, height))pd.loadPrcFileData("", "win-fixed-size 1")super().__init__()self.render.setTwoSided(True)self.disableMouse()self.__init_lights__()self.__init_camera__(fov=50, near=0.01, far=50, pos=[0.0, -7.0, 3.0], dir=[0.0, 1.2, -0.5])# init animation loop	assert len({v.shape[0] for v in vGRFs} | {m[0].shape[0] for m in motions}) == 1		nframes = motions[0][0].shape[0]self.animation_loop = AnimationLoop(length=nframes, fps=FRAMERATE, start=True)self.taskMgr.add(self.animation_loop, "animation_loop")# insolesif len(vGRFs) > 0:vGRFs_scale = 1 / torch.stack(list(vGRFs)).max()	for index, (value, label) in enumerate(zip(vGRFs, vGRF_labels)):x = index * 0.111 - 0.111 * (len(vGRFs) - 1) / 2self.add_insoles([x, self.cam.getPos()[1] + 0.60 + 0.08, self.cam.getPos()[2] - 0.435],vGRFs_scale * value, plate=True, label=label,)# get global trajectorytrajectories = torch.cat([motion[2] for motion in motions], dim=-2)global_trajectory = trajectories.mean(dim=-2)global_trajectory = util.gma(global_trajectory, size=30, std=30/3, dim=0)global_trajectory[..., 2] = 0.0c = 0.25global_bbox = trajectories.amax(dim=(0, 1)) - trajectories.amin(dim=(0, 1))global_position = global_trajectory.mean(dim=0)ground_grid = ((global_bbox[:2] + 3) / c).ceil()self._ground = Ground(self.render, grid=ground_grid, size=c*ground_grid, origin=global_position[:2],loop=self.animation_loop,trajectory=-global_trajectory,)for motion, label in zip(motions, motion_labels):angles, skeleton, trajectory = motion[0], motion[1].reshape(-1, 3), motion[2].reshape(-1, 3)trajectory = trajectory - global_trajectoryself._skeleton = Skeleton(self.render, skeleton,loop=self.animation_loop, angles=angles, trajectory=trajectory,label=label,)# Framerate buttonsbutton025 = DirectButton(text="0.25x", scale=0.05, pos=(-0.2, 0.0, 0.96), command=lambda: self.change_framerate(0.25))button050 = DirectButton(text="0.50x", scale=0.05, pos=(0.0, 0.0, 0.96), command=lambda: self.change_framerate(0.50))button100 = DirectButton(text="1.00x", scale=0.05, pos=(0.2, 0.0, 0.96), command=lambda: self.change_framerate(1.00))def change_framerate(self, rate):self.animation_loop.fps = rate * FRAMERATEdef __init_lights__(self):def point_light(position, color, name=""):light = pd.PointLight(name)light.setColor(color)light = self.render.attachNewNode(light)light.setPos(*position)self.render.setLight(light)intensity = 0.6point_light((5, 5, -5), (intensity, intensity, intensity, 1))point_light((0, 5, -5), (intensity, intensity, intensity, 1))point_light((5, 0, -5), (intensity, intensity, intensity, 1))def __init_camera__(self, **kwargs):if "near" in kwargs:self.camLens.setNear(kwargs["near"])if "far" in kwargs:self.camLens.setFar(kwargs["far"])		if "fov" in kwargs:self.camLens.setFov(kwargs["fov"])if "pos" in kwargs:self.cam.setPos(*kwargs["pos"])if "target" in kwargs:pos, target = torch.as_tensor(self.cam.getPos()), torch.as_tensor(kwargs["target"])dir = (target - pos).tolist()elif "dir" in kwargs:dir = kwargs["dir"]self.camLens.setViewVector(*dir,*kwargs.get("up", [0.0, 0.0, 1.0]),)def add_insoles(self, origin, forces, plate=False, label=None):insoles = InsolesPair(Insole.left(self.render, origin=[origin[0] - 0.021, origin[1], origin[2]], length=0.15, angle=10.0),Insole.right(self.render, origin=[origin[0] + 0.021, origin[1], origin[2]], length=0.15, angle=-10.0),loop=self.animation_loop, forces=forces.unbind(dim=-2),)width, depth, thickness = 0.108, 0.16, 0.01if plate:builder = GeomBuilder("insoles_plate")builder.box([origin[0], origin[1], origin[2] - thickness/2], [width, depth, thickness], color=(0.8, 0.8, 0.8, 1.0))self.render.attachNewNode(builder.build())if isinstance(label, str):text = pd.TextNode(label)text.setText(label)text.setAlign(pd.TextNode.ACenter)text = self.render.attachNewNode(text)text.setScale(thickness)text.setPos(origin[0], origin[1] - depth/2 - 1e-4, origin[2] - 0.8*thickness)		if __name__ == "__main__":import modelsfrom data import Datasetfrom argparse import ArgumentParserparser = ArgumentParser()parser.add_argument("-subj", "-subject", default="S9", help="Subject to be selected; default: S9")parser.add_argument("-seq", "-sequence", default="WalkRandomSlow", help="Sequence to be selected; default: WalkRandomSlow")parser.add_argument("-checkpoint", default="pretrained.tar")args = parser.parse_args()dataset = Dataset("{}-{}".format(args.subj, args.seq))item = dataset[0]angles, skeleton, trajectory = item["angles"], item["skeleton"], item["trajectory"]vGRFs_gt = item["forces"]positions = anim.FK(angles, skeleton, trajectory, TOPOLOGY)checkpoint = torch.load(args.checkpoint)model = models.DeepNetwork(state_dict=checkpoint["model"]).eval()with torch.no_grad():vGRFs_pred = model.vGRFs(positions.unsqueeze(0)).squeeze(0)vGRFs_abs_error = (vGRFs_gt - vGRFs_pred).abs()MocapAndvGRFsApp([(angles, skeleton, trajectory)],[vGRFs_gt, vGRFs_pred, vGRFs_abs_error],vGRF_labels=["Ground Truth", "Estimated", "Abs. Error"],).run()

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

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

相关文章

Node.js 包管理工具 - NPM 与 PNPM 清理缓存

NPM 清理缓存 1、基本介绍 npm 缓存是 npm 用来存储已下载包的地方&#xff0c;以加快后续安装速度 但是&#xff0c;有时缓存可能会损坏或占用过多磁盘空间&#xff0c;这时可以清理 npm 缓存 2、清理操作 执行如下指令&#xff0c;清理 npm 缓存 npm cache clean --for…

STM32F103_LL库+寄存器学习笔记05 - GPIO输入模式,捕获上升沿进入中断回调

导言 GPIO设置输入模式后&#xff0c;一般会用轮询的方式去查看GPIO的电平状态。比如&#xff0c;最常用的案例是用于检测按钮的当前状态&#xff08;是按下还是没按下&#xff09;。中断的使用一般用于计算脉冲的频率与计算脉冲的数量。 项目地址&#xff1a;https://github.…

【C++进阶二】string的模拟实现

【C进阶二】string的模拟实现 1.构造函数和C_strC_str: 2.operator[]3.拷贝构造3.1浅拷贝3.2深拷贝 4.赋值5.迭代器6.比较ascll码值的大小7.reverse扩容8.push_back尾插和append尾插9.10.insert10.1在pos位置前插入字符ch10.2在pos位置前插入字符串str 11.resize12.erase12.1从…

wokwi arduino mega 2560 - 点亮LED案例

截图&#xff1a; 点亮LED案例仿真截图 代码&#xff1a; unsigned long t[20]; // 定义一个数组t&#xff0c;用于存储20个LED的上次状态切换时间&#xff08;单位&#xff1a;毫秒&#xff09;void setup() {pinMode(13, OUTPUT); // 将引脚13设置为输出模式&#xff08;此…

vue3项目使用 python +flask 打包成桌面应用

server.py import os import sys from flask import Flask, send_from_directory# 获取静态文件路径 if getattr(sys, "frozen", False):# 如果是打包后的可执行文件base_dir sys._MEIPASS else:# 如果是开发环境base_dir os.path.dirname(os.path.abspath(__file…

后端学习day1-Spring(八股)--还剩9个没看

一、Spring 1.请你说说Spring的核心是什么 参考答案 Spring框架包含众多模块&#xff0c;如Core、Testing、Data Access、Web Servlet等&#xff0c;其中Core是整个Spring框架的核心模块。Core模块提供了IoC容器、AOP功能、数据绑定、类型转换等一系列的基础功能&#xff0c;…

LeetCode 第34、35题

LeetCode 第34题&#xff1a;在排序数组中查找元素的第一个和最后一个位置 题目描述 给你一个按照非递减顺序排列的整数数组nums&#xff0c;和一个目标值target。请你找出给定目标值在数组中的开始位置和结束位置。如果数组中不存在目标值target&#xff0c;返回[-1,1]。你必须…

告别分库分表,时序数据库 TDengine 解锁燃气监控新可能

达成效果&#xff1a; 从 MySQL 迁移至 TDengine 后&#xff0c;设备数据自动分片&#xff0c;运维更简单。 列式存储可减少 50% 的存储占用&#xff0c;单服务器即可支撑全量业务。 毫秒级漏气报警响应时间控制在 500ms 以内&#xff0c;提升应急管理效率。 新架构支持未来…

第十四届蓝桥杯真题

一.LED 先配置LED的八个引脚为GPIO_OutPut,锁存器PD2也是,然后都设置为起始高电平,生成代码时还要去解决引脚冲突问题 二.按键 按键配置,由原理图按键所对引脚要GPIO_Input 生成代码,在文件夹中添加code文件夹,code中添加fun.c、fun.h、headfile.h文件,去资源包中把lc…

《基于机器学习发电数据电量预测》开题报告

个人主页&#xff1a;大数据蟒行探索者 目录 一、选题背景、研究意义及文献综述 &#xff08;一&#xff09;选题背景 &#xff08;二&#xff09;选题意义 &#xff08;三&#xff09;文献综述 1. 国内外研究现状 2. 未来方向展望 二、研究的基本内容&#xff0c;拟解…

UWP程序用多页面实现应用实例多开

Windows 10 IoT ARM64平台下&#xff0c;UWP应用和MFC程序不一样&#xff0c;同时只能打开一个应用实例。以串口程序为例&#xff0c;如果用户希望同时打开多个应用实例&#xff0c;一个应用实例打开串口1&#xff0c;一个应用实例打开串口2&#xff0c;那么我们可以加载多个页…

Springboot整合Netty简单实现1对1聊天(vx小程序服务端)

本文功能实现较为简陋&#xff0c;demo内容仅供参考&#xff0c;有不足之处还请指正。 背景 一个小项目&#xff0c;用于微信小程序的服务端&#xff0c;需要实现小程序端可以和他人1对1聊天 实现功能 Websocket、心跳检测、消息持久化、离线消息存储 Netty配置类 /*** au…

GitLab 中文版17.10正式发布,27项重点功能解读【二】

GitLab 是一个全球知名的一体化 DevOps 平台&#xff0c;很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab 是 GitLab 在中国的发行版&#xff0c;专门为中国程序员服务。可以一键式部署极狐GitLab。 学习极狐GitLab 的相关资料&#xff1a; 极狐GitLab 官网极狐…

好消息!软航文档控件(NTKO WebOffice)在Chrome 133版本上提示扩展已停用的解决方案

软航文档控件现有版本依赖Manifest V2扩展技术支持才能正常运行&#xff0c;然而这个扩展技术到2025年6月在Chrome高版本上就彻底不支持了&#xff0c;现在Chrome 133开始的版本已经开始弹出警告&#xff0c;必须手工开启扩展支持才能正常运行。那么如何解决这个技术难题呢&…

字典树与01trie

字典树简介 当我们通过字典查一个字或单词的时候&#xff0c;我们会通过前缀或关键字的来快速定位一个字的位置&#xff0c;进行快速查找。 字典树就是类似字典中索引表的一种数据结构&#xff0c;能够帮助我们快速定位一个字符串的位置。 字典树是一种存储字符串的数据结构…

二十五、实战开发 uni-app x 项目(仿京东)- 前后端轮播图

定义了一个名为 Swiper 的Java类,用于表示一个轮播图实体。它使用了 Jakarta Persistence API (JPA) 来映射数据库表,并使用了 Lombok 库来简化代码。以下是对代码的详细讲解: 1. 包声明 package com.jd.jdmall.model; 这行代码声明了该类所在的包路径为 com.jd.jdmall.mode…

游戏摇杆开发:利用 Windows API 实现摇杆输入捕获

在现代游戏开发中&#xff0c;游戏摇杆&#xff08;Joystick&#xff09;作为一种重要的输入设备&#xff0c;能够为玩家提供更加沉浸式的游戏体验。Windows 操作系统提供了一系列 API 函数&#xff0c;允许开发者轻松地捕获和处理游戏摇杆的输入。本文将介绍如何使用 Windows …

Ceph集群2025(Squid版)快速对接K8S cephFS文件存储

ceph的块存储太简单了。所以不做演示 查看集群 创建一个 CephFS 文件系统 # ceph fs volume create cephfs01 需要创建一个子卷# ceph fs subvolume create cephfs01 my-subvol -----------------#以下全部自动创建好 # ceph fs ls name: cephfs01, metadata pool: c…

Python中数据结构元组详解

在Python中&#xff0c;元组&#xff08;Tuple&#xff09;是一种不可变的序列类型&#xff0c;常用于存储一组有序的数据。与列表&#xff08;List&#xff09;不同&#xff0c;元组一旦创建&#xff0c;其内容无法修改。本文将详细介绍元组的基本操作、常见运算、内置函数以及…

游戏引擎学习第183天

回顾和今天的计划 我对接下来的进展感到非常兴奋。虽然我们可能会遇到一些问题&#xff0c;但昨天我们差不多完成了将所有内容迁移到新的日志系统的工作&#xff0c;我们正在把一些内容整合进来&#xff0c;甚至是之前通过不同方式记录时间戳的旧平台层部分&#xff0c;现在也…