include file="*.html" 时出现乱码解决方案

问题描述:<%@ include file="*.html" %> 的中文乱码问题

要解决这个问题,当然最简单的就是在每个被 include 的文件第一行,加上

<%@ page contentType="text/html;charset=gb2312" %>
这样一定可以确保中文 jsp 档不会出现乱码,只不过,一旦程序修改成这样的模式,这种程序就无法在旧的
jsp/servlet container 上执行了,因为旧的规格是不允被 include 档案中再出现
<%@ page ... %> 这样的定义的。

况且,就算你愿意为了 Tomcat 5.0.x 特别维护一套不同版本的 Source Code,你会遇到重大的挫折,因为 Tomcat 5.0.x 版在 charset 的设定上,会特别检查include 别人的程序与被人include 的程序,这二个程序中所定义的 charset 是不是一样,如果不一样,在编译时就会产生错误。更恐怖的是,竟然还分大小写,比如说:"gb2312" "GB2312" 这样的定义,在 Tomcat 的认定上是不同的。

更好的解决方案
在 Tomcat 5.0.x 中,Tomcat 支持了 JSP 2.0 的规格,同时也支持了部分 J2EE 1.4 的规格,在 J2EE 1.4 的规格中,有关 JSP 的部份,有一个 <jsp-config> 的 XML Tag,这个 XML 区块用来定义与 JSP 相关的特殊属性,包含采用的 taglib 与 以下说明的 <jsp-property-group> ,而解决 include 档中文问题的方法就定义在 <jsp-roperty-group> 中。

在当前应用系统的web.xml里加入jsp-config代码:

<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee  http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4">
<jsp-config>
    <jsp-property-group>  
        <description>     
            Special property group for JSP Configuration JSP example.  
        </description>  
        <display-name>JSPConfiguration</display-name>  
        <url-pattern>*.jsp</url-pattern>  
        <el-ignored>true</el-ignored>  
        <page-encoding>GB2312</page-encoding>  
        <scripting-invalid>false</scripting-invalid>  
        <include-prelude></include-prelude>  
        <include-coda></include-coda>  
       
  <description>     
            Special property group for JSP Configuration JSP example.  
        </description>  
        <display-name>JSPConfiguration</display-name>  
        <url-pattern>*.html</url-pattern>  
        <el-ignored>true</el-ignored>  
        <page-encoding>GB2312</page-encoding>  
        <scripting-invalid>false</scripting-invalid>  
        <include-prelude></include-prelude>  
        <include-coda></include-coda>
    </jsp-property-group>
</jsp-config>


  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>index.html</welcome-file> 
  </welcome-file-list>   

... ...

</webapp>

 

说明:<jsp-config>里的定义,就是通知当前应用服务器,当前应用系统下,所有的 .jsp, .html 文件,若是没有定义contentType="text/html;charset=gb2312" 时,就会采用预设的 "GB2312" 字符集去处理,如此,就不须要在每个 include 的档案第一行加上 contentType="text/html;charset=gb2312" 了。

 

============================================================================

注:

<jsp-config>标签使用详解

<jsp-config> 包括<taglib> 和<jsp-property-group> 两个子元素。
    
    其中<taglib>元素在JSP 1.2时就已经存在;而<jsp-property-group>是JSP 2.0 新增的元素。
    <jsp-property-group>元素主要有八个子元素,它们分别为:
    
    1.<description>:设定的说明;
    2.<display-name>:设定名称;
    3.<url-pattern>:设定值所影响的范围,如:/CH2 或 /*.jsp;
    4.<el-ignored>:若为true,表示不支持EL 语法;
    5.<scripting-invalid>:若为true,表示不支持<% scripting %>语法;
    6.<page-encoding>:设定JSP 网页的编码;
    7.<include-prelude>:设置JSP 网页的抬头,扩展名为.jspf;
    8.<include-coda>:设置JSP 网页的结尾,扩展名为.jspf。

 



Trackback: http://tb.blog.youkuaiyun.com/TrackBack.aspx?PostId=1266394

 
import tkinter as tk from tkinter import ttk, messagebox, scrolledtext, simpledialog import traceback import sys import os # 添加当前目录到系统路径,确保导入成功 current_dir = os.path.dirname(os.path.abspath(__file__)) sys.path.insert(0, current_dir) try: from fat32_reader import FAT32Writer, FAT32Analyzer except ImportError as e: print(f"导入错误: {e}") print(f"当前目录: {current_dir}") print(f"Python 路径: {sys.path}") # 如果导入失败,显示错误信息并退出 root = tk.Tk() root.withdraw() messagebox.showerror("导入错误", f"无法导入 FAT32 模块: {e}\n请确保 fat32_reader.py 文件存在") sys.exit(1) class FAT32GUI: """FAT32文件系统图形界面""" def __init__(self, fat32_reader): self.reader = fat32_reader self.analyzer = FAT32Analyzer(self.reader) # 创建主窗口 self.root = tk.Tk() self.root.title(f"FAT32 文件系统可视化 - {self.reader.get_volume_label()}") self.root.geometry("1400x900") # 创建主框架 main_frame = tk.Frame(self.root) main_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10) # 创建顶部控制面板 control_frame = tk.Frame(main_frame) control_frame.pack(fill=tk.X, pady=(0, 10)) # 创建按钮 self.create_btn = tk.Button( control_frame, text="新建文件", command=self.create_file_dialog, width=15 ) self.create_btn.pack(side=tk.LEFT, padx=5) self.refresh_btn = tk.Button( control_frame, text="刷新视图", command=self.refresh_view, width=15 ) self.refresh_btn.pack(side=tk.LEFT, padx=5) # 创建过滤选项 filter_frame = tk.LabelFrame(control_frame, text="显示选项") filter_frame.pack(side=tk.LEFT, padx=20) self.show_hidden_var = tk.BooleanVar(value=False) self.show_system_var = tk.BooleanVar(value=False) self.show_special_var = tk.BooleanVar(value=False) tk.Checkbutton( filter_frame, text="显示隐藏文件", variable=self.show_hidden_var, command=self.refresh_view ).pack(side=tk.LEFT, padx=5) tk.Checkbutton( filter_frame, text="显示系统文件", variable=self.show_system_var, command=self.refresh_view ).pack(side=tk.LEFT, padx=5) tk.Checkbutton( filter_frame, text="显示系统目录", variable=self.show_special_var, command=self.refresh_view ).pack(side=tk.LEFT, padx=5) # 创建主分割面板 main_paned = tk.PanedWindow(main_frame, orient=tk.HORIZONTAL, sashrelief=tk.RAISED, sashwidth=4) main_paned.pack(fill=tk.BOTH, expand=True) # ========== 左侧目录树 ========== left_frame = tk.Frame(main_paned) main_paned.add(left_frame, width=400) tree_frame = tk.LabelFrame(left_frame, text="目录结构") tree_frame.pack(fill=tk.BOTH, expand=True) # 创建树视图 tree_scroll = ttk.Scrollbar(tree_frame, orient="vertical") tree_scroll.pack(side=tk.RIGHT, fill=tk.Y) self.tree = ttk.Treeview( tree_frame, columns=('Name', 'Size', 'Cluster', 'Created', 'Modified'), show='tree headings', yscrollcommand=tree_scroll.set ) tree_scroll.config(command=self.tree.yview) # 配置列 self.tree.heading('#0', text='类型', anchor=tk.W) self.tree.heading('Name', text='文件名', anchor=tk.W) self.tree.heading('Size', text='大小', anchor=tk.W) self.tree.heading('Cluster', text='起始簇', anchor=tk.W) self.tree.heading('Created', text='创建间', anchor=tk.W) self.tree.heading('Modified', text='修改间', anchor=tk.W) self.tree.column('#0', width=60, minwidth=60) self.tree.column('Name', width=250, minwidth=150) self.tree.column('Size', width=100, minwidth=80) self.tree.column('Cluster', width=80, minwidth=60) self.tree.column('Created', width=180, minwidth=120) self.tree.column('Modified', width=180, minwidth=120) self.tree.pack(fill=tk.BOTH, expand=True) # ========== 右侧内容区域 ========== right_frame = tk.Frame(main_paned) main_paned.add(right_frame) # 创建垂直分割面板 right_paned = tk.PanedWindow(right_frame, orient=tk.VERTICAL, sashrelief=tk.RAISED, sashwidth=4) right_paned.pack(fill=tk.BOTH, expand=True) # 磁盘布局可视化 cluster_frame = tk.LabelFrame(right_paned, text="磁盘布局可视化") right_paned.add(cluster_frame, height=450) # 创建画布和滚动条 canvas_frame = tk.Frame(cluster_frame) canvas_frame.pack(fill=tk.BOTH, expand=True, padx=5, pady=5) h_scroll = ttk.Scrollbar(canvas_frame, orient=tk.HORIZONTAL) v_scroll = ttk.Scrollbar(canvas_frame, orient=tk.VERTICAL) self.canvas = tk.Canvas( canvas_frame, bg='white', xscrollcommand=h_scroll.set, yscrollcommand=v_scroll.set ) h_scroll.pack(side=tk.BOTTOM, fill=tk.X) v_scroll.pack(side=tk.RIGHT, fill=tk.Y) self.canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True) h_scroll.config(command=self.canvas.xview) v_scroll.config(command=self.canvas.yview) # 文件内容/详细信息 content_frame = tk.LabelFrame(right_paned, text="文件内容/详细信息") right_paned.add(content_frame) # 创建标签页 notebook_frame = tk.Frame(content_frame) notebook_frame.pack(fill=tk.BOTH, expand=True, padx=5, pady=5) self.notebook = ttk.Notebook(notebook_frame) self.notebook.pack(fill=tk.BOTH, expand=True) # 文件内容标签页 self.content_tab = ttk.Frame(self.notebook) self.notebook.add(self.content_tab, text="文件内容") text_frame = tk.Frame(self.content_tab) text_frame.pack(fill=tk.BOTH, expand=True) text_scroll = ttk.Scrollbar(text_frame) text_scroll.pack(side=tk.RIGHT, fill=tk.Y) self.text = tk.Text( text_frame, wrap=tk.WORD, yscrollcommand=text_scroll.set, font=('Consolas', 10) ) self.text.pack(side=tk.LEFT, fill=tk.BOTH, expand=True) text_scroll.config(command=self.text.yview) # 磁盘信息标签页 self.info_tab = ttk.Frame(self.notebook) self.notebook.add(self.info_tab, text="磁盘信息") info_frame = tk.Frame(self.info_tab) info_frame.pack(fill=tk.BOTH, expand=True) info_scroll = ttk.Scrollbar(info_frame) info_scroll.pack(side=tk.RIGHT, fill=tk.Y) self.info_text = tk.Text( info_frame, wrap=tk.WORD, yscrollcommand=info_scroll.set, state='disabled', font=('Consolas', 10) ) self.info_text.pack(side=tk.LEFT, fill=tk.BOTH, expand=True) info_scroll.config(command=self.info_text.yview) # 属性信息标签页 self.attr_tab = ttk.Frame(self.notebook) self.notebook.add(self.attr_tab, text="属性信息") attr_frame = tk.Frame(self.attr_tab) attr_frame.pack(fill=tk.BOTH, expand=True) attr_scroll = ttk.Scrollbar(attr_frame) attr_scroll.pack(side=tk.RIGHT, fill=tk.Y) self.attr_text = tk.Text( attr_frame, wrap=tk.WORD, yscrollcommand=attr_scroll.set, font=('Consolas', 10) ) self.attr_text.pack(side=tk.LEFT, fill=tk.BOTH, expand=True) attr_scroll.config(command=self.attr_text.yview) # 创建状态栏 status_frame = tk.Frame(self.root, height=25) status_frame.pack(side=tk.BOTTOM, fill=tk.X) self.status_var = tk.StringVar() self.status_var.set("就绪") status_bar = tk.Label( status_frame, textvariable=self.status_var, bd=1, relief=tk.SUNKEN, anchor=tk.W, padx=10 ) status_bar.pack(fill=tk.X) # 初始化数据 self.refresh_data() # 绑定事件 self.tree.bind("<<TreeviewSelect>>", self._on_tree_select) self.selected_clusters = [] # 添加右键菜单 self.context_menu = tk.Menu(self.root, tearoff=0) self.context_menu.add_command(label="查看文件内容", command=self.view_file_content) self.context_menu.add_command(label="查看簇链", command=self.view_cluster_chain) self.context_menu.add_command(label="查看属性", command=self.view_attributes) self.tree.bind("<Button-3>", self.show_context_menu) def refresh_data(self): """刷新数据""" try: self.status_var.set("正在读取FAT表...") self.root.update_idletasks() # 读取FAT表 self.fat = self.reader.read_fat_table() self.total_clusters = len(self.fat) // 4 # 获取簇状态 self.cluster_status = self.analyzer.get_cluster_status() # 填充目录树 self._populate_tree() # 绘制簇图 self._draw_clusters() # 更新磁盘信息 self._update_disk_info() self.status_var.set("就绪") except Exception as e: self.status_var.set(f"错误: {str(e)}") messagebox.showerror("初始化错误", f"无法读取FAT表: {str(e)}") traceback.print_exc() def refresh_view(self): """刷新视图""" try: self.status_var.set("刷新中...") self.root.update_idletasks() # 重新读取FAT表 self.fat = self.reader.read_fat_table() self.total_clusters = len(self.fat) // 4 self.cluster_status = self.analyzer.get_cluster_status() # 重新填充目录树 self._populate_tree() # 重新绘制簇图 self._draw_clusters() # 更新磁盘信息 self._update_disk_info() # 清空文件内容显示 self.text.delete('1.0', tk.END) self.attr_text.delete('1.0', tk.END) self.status_var.set("刷新完成") except Exception as e: self.status_var.set(f"刷新失败: {str(e)}") messagebox.showerror("刷新错误", str(e)) traceback.print_exc() def _update_disk_info(self): """更新磁盘信息标签页内容""" info_text = f"""FAT32 文件系统信息 卷标: {self.reader.get_volume_label()} 每扇区字节数: {self.reader.bytes_per_sector} 每簇扇区数: {self.reader.sectors_per_cluster} 簇大小: {self.reader.sectors_per_cluster * self.reader.bytes_per_sector} 字节 保留扇区数: {self.reader.reserved_sector_count} FAT表数量: {self.reader.num_fats} 每FAT表扇区数: {self.reader.sectors_per_fat} 根目录起始簇号: {self.reader.root_cluster} 总扇区数: {self.reader.total_sectors_32} 总簇数: {self.analyzer.total_clusters} FAT表偏移: 0x{self.reader.fat_offset:X} 数据区偏移: 0x{self.reader.data_offset:X} 空闲簇数: {self.cluster_status.count(0)} 已分配簇数: {self.cluster_status.count(1)} 保留簇数: {self.cluster_status.count(3)} """ self.info_text.config(state='normal') self.info_text.delete('1.0', tk.END) self.info_text.insert(tk.END, info_text) self.info_text.config(state='disabled') def _populate_tree(self): """填充目录树""" self.tree.delete(*self.tree.get_children()) self._add_dir(self.reader.root_cluster, '', "根目录", visited=set()) def _add_dir(self, cluster, parent, name, visited=None): """递归添加目录和文件到树中""" if visited is None: visited = set() if cluster in visited: return visited.add(cluster) # 添加目录节点 node = self.tree.insert( parent, 'end', text="📁", open=True, values=("目录", name, "", cluster, "", "") ) # 读取目录内容 try: # 根据用户设置决定是否包含特殊目录 include_special = self.show_special_var.get() entries = self.analyzer.read_directory(cluster, include_special=include_special) for entry in entries: # 应用过滤设置 if not self.show_hidden_var.get() and entry.get('is_hidden', False): continue if not self.show_system_var.get() and entry.get('is_system', False): continue if entry['is_dir']: # 添加子目录 self._add_dir(entry['start_cluster'], node, entry['name'], visited) else: # 添加文件 size_str = self._format_size(entry['size']) self.tree.insert( node, 'end', text="📄", values=( "文件", entry['name'], size_str, entry['start_cluster'], entry['created'], entry['modified'] ) ) except Exception as e: print(f"读取目录错误: {str(e)}") self.tree.insert( node, 'end', text="⚠️", values=("错误", f"读取错误: {str(e)}", "", "", "", "") ) def _format_size(self, size): """格式化文件大小 - 确保单位正确""" if size < 1024: return f"{size} B" elif size < 1024 * 1024: return f"{size/1024:.2f} KB" else: return f"{size/(1024*1024):.2f} MB" def _draw_clusters(self, highlight_clusters=None): """绘制簇状态可视化 - 优化布局""" self.canvas.delete('all') cols = 80 size = 8 pad = 1 max_show = min(len(self.cluster_status), 8000) # 最多显示8000个簇 # 添加标题 self.canvas.create_text( 10, 10, anchor='nw', text=f"簇状态可视化 (显示前 {max_show} 个簇)", font=('Arial', 10, 'bold'), fill="#333" ) # 计算最大行数 max_rows = (max_show + cols - 1) // cols # 绘制簇 for i in range(max_show): row = i // cols col = i % cols x0 = col * (size + pad) + 10 y0 = row * (size + pad) + 40 status = self.cluster_status[i] if status == 0: color = '#4CAF50' # 空闲 - 绿色 elif status == 1: color = '#F44336' # 已分配 - 红色 elif status == 2: color = '#FF9800' # 结束簇 - 橙色 else: color = '#9E9E9E' # 保留簇 - 灰色 if highlight_clusters and i in highlight_clusters: color = '#2196F3' # 选中文件簇链 - 蓝色 self.canvas.create_rectangle(x0, y0, x0+size, y0+size, fill=color, outline=color) # 将图例放在簇图下方 legend_y = max_rows * (size + pad) + 60 # 添加图例标题 self.canvas.create_text( 10, legend_y - 20, anchor='nw', text="图例:", font=('Arial', 9, 'bold'), fill="#333" ) # 添加图例项 legend_items = [ ('空闲簇', '#4CAF50'), ('已分配', '#F44336'), ('结束簇', '#FF9800'), ('保留簇', '#9E9E9E'), ('选中文件', '#2196F3') ] for idx, (text, color) in enumerate(legend_items): x_pos = 10 + idx * 120 self.canvas.create_rectangle( x_pos, legend_y, x_pos + 15, legend_y + 15, fill=color, outline='#333' ) self.canvas.create_text( x_pos + 20, legend_y + 7, anchor='w', text=text, font=('Arial', 9), fill="#333" ) # 添加统计信息 stats_text = f"总簇数: {len(self.cluster_status)} | " \ f"空闲簇: {self.cluster_status.count(0)} | " \ f"已分配簇: {self.cluster_status.count(1)} | " \ f"保留簇: {self.cluster_status.count(3)}" self.canvas.create_text( 10, legend_y + 30, anchor='nw', text=stats_text, font=('Arial', 9), fill="#333" ) # 设置画布滚动区域 self.canvas.config(scrollregion=(0, 0, 700, legend_y + 60)) def _on_tree_select(self, event): """处理目录树选择事件""" item = self.tree.selection() if not item: return node = item[0] values = self.tree.item(node, 'values') # 如果没有值,跳过 if not values: return # 如果是文件节点 if values[0] == "文件": file_name = values[1] size_str = values[2] start_cluster = int(values[3]) size = self._parse_size(size_str) # 获取文件簇链 clusters = self.analyzer.get_file_clusters(start_cluster) self.selected_clusters = clusters # 高亮显示文件簇链 highlight_clusters = [c for c in clusters if c < 8000] # 只高亮前8000个簇 self._draw_clusters(highlight_clusters=highlight_clusters) # 显示文件信息 self.text.config(state='normal') self.text.delete('1.0', tk.END) self.text.insert(tk.END, f"文件信息: {file_name}\n") self.text.insert(tk.END, "-" * 80 + "\n") self.text.insert(tk.END, f"大小: {size_str}\n") self.text.insert(tk.END, f"起始簇: {start_cluster}\n") self.text.insert(tk.END, f"簇链: {clusters}\n") self.text.insert(tk.END, f"创建间: {values[4]}\n") self.text.insert(tk.END, f"修改间: {values[5]}\n") self.text.insert(tk.END, "-" * 80 + "\n\n") # 读取文件内容 try: data = self._read_file_content(clusters, size) # 尝试解码为文本 try: text_content = data.decode('utf-8', errors='replace') self.text.insert(tk.END, "文件内容:\n") self.text.insert(tk.END, "-" * 80 + "\n") self.text.insert(tk.END, text_content) except UnicodeDecodeError: # 显示十六进制预览 self.text.insert(tk.END, "十六进制预览 (仅显示前1KB):\n") self.text.insert(tk.END, "-" * 80 + "\n") hex_view = "" for i in range(0, min(len(data), 1024), 16): chunk = data[i:i+16] hexstr = ' '.join(f'{b:02X}' for b in chunk) asciistr = ''.join(chr(b) if 32 <= b < 127 else '.' for b in chunk) hex_view += f"{i:04X}: {hexstr.ljust(47)} {asciistr}\n" self.text.insert(tk.END, hex_view) except Exception as e: self.text.insert(tk.END, f"读取文件内容失败: {str(e)}") # 切换到文件内容标签页 self.notebook.select(self.content_tab) else: self.selected_clusters = [] self._draw_clusters() self.text.config(state='normal') self.text.delete('1.0', tk.END) self.text.insert(tk.END, f"目录信息: {values[1]}\n") self.text.insert(tk.END, f"起始簇: {values[3] if values else '未知'}\n") self.text.config(state='disabled') def _parse_size(self, size_str): """解析文件大小字符串为字节数""" if 'KB' in size_str: return int(float(size_str.replace(' KB', '')) * 1024) elif 'MB' in size_str: return int(float(size_str.replace(' MB', '')) * 1024 * 1024) elif 'B' in size_str: return int(size_str.replace(' B', '')) return 0 def _read_file_content(self, clusters, size): """读取文件内容""" data = b'' for c in clusters: data += self.reader.read_cluster(c) if len(data) >= size: break return data[:size] def show_context_menu(self, event): """显示右键上下文菜单""" item = self.tree.identify_row(event.y) if item: self.tree.selection_set(item) self.context_menu.post(event.x_root, event.y_root) def view_file_content(self): """查看文件内容(已通过树选择实现)""" pass def view_cluster_chain(self): """查看簇链(已通过树选择实现)""" pass def view_attributes(self): """查看文件属性""" item = self.tree.selection() if not item: return node = item[0] values = self.tree.item(node, 'values') if not values or values[0] != "文件": return self.attr_text.delete('1.0', tk.END) self.attr_text.insert(tk.END, f"文件属性: {values[1]}\n\n") # 显示文件在树中的详细信息 self.attr_text.insert(tk.END, "基本信息:\n") self.attr_text.insert(tk.END, f"文件名: {values[1]}\n") self.attr_text.insert(tk.END, f"大小: {values[2]}\n") self.attr_text.insert(tk.END, f"起始簇: {values[3]}\n") self.attr_text.insert(tk.END, f"创建间: {values[4]}\n") self.attr_text.insert(tk.END, f"修改间: {values[5]}\n\n") # 获取文件簇链 clusters = self.analyzer.get_file_clusters(int(values[3])) self.attr_text.insert(tk.END, f"簇链 ({len(clusters)} 簇):\n") self.attr_text.insert(tk.END, f"{clusters}\n") # 切换到属性标签页 self.notebook.select(self.attr_tab) def create_file_dialog(self): """创建新文件对话框""" filename = simpledialog.askstring("新建文件", "输入文件名(支持长文件名):") if not filename: return # 检查文件名是否包含非法字符 invalid_chars = ['\\', '/', ':', '*', '?', '"', '<', '>', '|'] if any(char in filename for char in invalid_chars): messagebox.showerror("错误", f"文件名包含非法字符: {''.join(invalid_chars)}") return content = simpledialog.askstring("新建文件", "输入文件内容:") if content is None: return try: self.status_var.set(f"正在写入文件 {filename}...") self.root.update_idletasks() # 写入文件 clusters = self.reader.write_file_to_root(filename, content.encode('utf-8')) self.status_var.set(f"文件 {filename} 写入成功,刷新中...") self.root.update_idletasks() # 刷新视图 self.refresh_data() messagebox.showinfo("成功", f"文件 {filename} 已成功写入根目录!") self.status_var.set("就绪") # 高亮显示新文件的簇链 highlight_clusters = [c for c in clusters if c < 8000] self._draw_clusters(highlight_clusters=highlight_clusters) except Exception as e: self.status_var.set(f"写入失败: {str(e)}") messagebox.showerror("写入失败", str(e)) traceback.print_exc() def run(self): """启动GUI主循环""" self.root.mainloop() if __name__ == "__main__": # 获取设备路径 device_path = input("请输入U盘设备路径(例如: /dev/sdb1 或 \\\\.\\PhysicalDrive1): ") try: # 创建FAT32读写器 writer = FAT32Writer(device_path) # 创建并运行GUI gui = FAT32GUI(writer) gui.run() # 关闭资源 writer.close() except Exception as e: print(f"发生错误: {str(e)}") traceback.print_exc() input("按回车键退出..."输出界面数据填充有误
07-06
wjs@wjs-desktop:~/Drone_Slam$ ros2 launch fishbot_grapher test_grapher_3.launch.py [INFO] [launch]: All log files can be found below /home/wjs/.ros/log/2025-07-27-21-26-18-750077-wjs-desktop-2603 [INFO] [launch]: Default logging verbosity is set to INFO pkg_share =/home/wjs/Drone_Slam/install/fishbot_grapher/share/fishbot_grapher<== model_path =/home/wjs/Drone_Slam/install/fishbot_grapher/share/fishbot_grapher/urdf/fishbot_base.urdf<== [INFO] [sllidar_node-1]: process started with pid [2604] [INFO] [wit_ros2_imu-2]: process started with pid [2606] [INFO] [test01-3]: process started with pid [2608] [INFO] [robot_state_publisher-4]: process started with pid [2610] [INFO] [cartographer_node-5]: process started with pid [2612] [INFO] [cartographer_occupancy_grid_node-6]: process started with pid [2616] [sllidar_node-1] [INFO] [1753622779.123428206] [sllidar_node]: SLLidar running on ROS2 package SLLidar.ROS2 SDK Version:1.0.1, SLLIDAR SDK Version:2.0.0 [sllidar_node-1] [ERROR] [1753622779.166949150] [sllidar_node]: Error, operation time out. SL_RESULT_OPERATION_TIMEOUT! [ERROR] [sllidar_node-1]: process has died [pid 2604, exit code 255, cmd '/home/wjs/Drone_Slam/install/sllidar_ros2/lib/sllidar_ros2/sllidar_node --ros-args -r __node:=sllidar_node --params-file /tmp/launch_params_09et7i92']. [robot_state_publisher-4] [WARN] [1753622779.340852788] [robot_state_publisher]: No robot_description parameter, but command-line argument available. Assuming argument is name of URDF file. This backwards compatibility fallback will be removed in the future. [robot_state_publisher-4] [INFO] [1753622779.403618429] [robot_state_publisher]: got segment base_link [robot_state_publisher-4] [INFO] [1753622779.404146730] [robot_state_publisher]: got segment imu_link [robot_state_publisher-4] [INFO] [1753622779.404233622] [robot_state_publisher]: got segment laser_link [cartographer_node-5] [INFO] [1753622779.592485766] [cartographer logger]: I0727 21:26:19.000000 2612 configuration_file_resolver.cc:41] Found '/home/wjs/Drone_Slam/install/fishbot_grapher/share/fishbot_grapher/config/test02.lua' for 'test02.lua'. [cartographer_node-5] [INFO] [1753622779.600612764] [cartographer logger]: I0727 21:26:19.000000 2612 configuration_file_resolver.cc:41] Found '/opt/ros/humble/share/cartographer/configuration_files/map_builder.lua' for 'map_builder.lua'. [cartographer_node-5] [INFO] [1753622779.600914554] [cartographer logger]: I0727 21:26:19.000000 2612 configuration_file_resolver.cc:41] Found '/opt/ros/humble/share/cartographer/configuration_files/map_builder.lua' for 'map_builder.lua'. [cartographer_node-5] [INFO] [1753622779.602523216] [cartographer logger]: I0727 21:26:19.000000 2612 configuration_file_resolver.cc:41] Found '/opt/ros/humble/share/cartographer/configuration_files/pose_graph.lua' for 'pose_graph.lua'. [cartographer_node-5] [INFO] [1753622779.602795339] [cartographer logger]: I0727 21:26:19.000000 2612 configuration_file_resolver.cc:41] Found '/opt/ros/humble/share/cartographer/configuration_files/pose_graph.lua' for 'pose_graph.lua'. [cartographer_node-5] [INFO] [1753622779.604405038] [cartographer logger]: I0727 21:26:19.000000 2612 configuration_file_resolver.cc:41] Found '/opt/ros/humble/share/cartographer/configuration_files/trajectory_builder.lua' for 'trajectory_builder.lua'. [cartographer_node-5] [INFO] [1753622779.604828741] [cartographer logger]: I0727 21:26:19.000000 2612 configuration_file_resolver.cc:41] Found '/opt/ros/humble/share/cartographer/configuration_files/trajectory_builder.lua' for 'trajectory_builder.lua'. [cartographer_node-5] [INFO] [1753622779.606033589] [cartographer logger]: I0727 21:26:19.000000 2612 configuration_file_resolver.cc:41] Found '/opt/ros/humble/share/cartographer/configuration_files/trajectory_builder_2d.lua' for 'trajectory_builder_2d.lua'. [cartographer_node-5] [INFO] [1753622779.606329861] [cartographer logger]: I0727 21:26:19.000000 2612 configuration_file_resolver.cc:41] Found '/opt/ros/humble/share/cartographer/configuration_files/trajectory_builder_2d.lua' for 'trajectory_builder_2d.lua'. [cartographer_node-5] [INFO] [1753622779.607970765] [cartographer logger]: I0727 21:26:19.000000 2612 configuration_file_resolver.cc:41] Found '/opt/ros/humble/share/cartographer/configuration_files/trajectory_builder_3d.lua' for 'trajectory_builder_3d.lua'. [cartographer_node-5] [INFO] [1753622779.608301075] [cartographer logger]: I0727 21:26:19.000000 2612 configuration_file_resolver.cc:41] Found '/opt/ros/humble/share/cartographer/configuration_files/trajectory_builder_3d.lua' for 'trajectory_builder_3d.lua'. [cartographer_node-5] F0727 21:26:19.623965 2612 lua_parameter_dictionary.cc:399] Check failed: HasKey(key) Key 'collate_landmarks' not in dictionary: [cartographer_node-5] { [cartographer_node-5] collate_fixed_frame = true, [cartographer_node-5] trajectory_builder_2d = { [cartographer_node-5] adaptive_voxel_filter = { [cartographer_node-5] max_length = 0.500000, [cartographer_node-5] max_range = 50.000000, [cartographer_node-5] min_num_points = 200.000000, [cartographer_node-5] }, [cartographer_node-5] ceres_scan_matcher = { [cartographer_node-5] ceres_solver_options = { [cartographer_node-5] max_num_iterations = 20.000000, [cartographer_node-5] num_threads = 1.000000, [cartographer_node-5] use_nonmonotonic_steps = false, [cartographer_node-5] }, [cartographer_node-5] occupied_space_weight = 1.000000, [cartographer_node-5] rotation_weight = 40.000000, [cartographer_node-5] translation_weight = 10.000000, [cartographer_node-5] }, [cartographer_node-5] imu_gravity_time_constant = 10.000000, [cartographer_node-5] loop_closure_adaptive_voxel_filter = { [cartographer_node-5] max_length = 0.900000, [cartographer_node-5] max_range = 50.000000, [cartographer_node-5] min_num_points = 100.000000, [cartographer_node-5] }, [cartographer_node-5] max_range = 8.000000, [cartographer_node-5] max_z = 2.000000, [cartographer_node-5] min_range = 0.300000, [cartographer_node-5] min_z = -0.800000, [cartographer_node-5] missing_data_ray_length = 1.000000, [cartographer_node-5] motion_filter = { [cartographer_node-5] max_angle_radians = 0.017453, [cartographer_node-5] max_distance_meters = 0.200000, [cartographer_node-5] max_time_seconds = 5.000000, [cartographer_node-5] }, [cartographer_node-5] num_accumulated_range_data = 1.000000, [cartographer_node-5] pose_extrapolator = { [cartographer_node-5] constant_velocity = { [cartographer_node-5] imu_gravity_time_constant = 10.000000, [cartographer_node-5] pose_queue_duration = 0.001000, [cartographer_node-5] }, [cartographer_node-5] imu_based = { [cartographer_node-5] gravity_constant = 9.806000, [cartographer_node-5] imu_acceleration_weight = 1.000000, [cartographer_node-5] imu_rotation_weight = 1.000000, [cartographer_node-5] odometry_rotation_weight = 1.000000, [cartographer_node-5] odometry_translation_weight = 1.000000, [cartographer_node-5] pose_queue_duration = 5.000000, [cartographer_node-5] pose_rotation_weight = 1.000000, [cartographer_node-5] pose_translation_weight = 1.000000, [cartographer_node-5] solver_options = { [cartographer_node-5] max_num_iterations = 10.000000, [cartographer_node-5] num_threads = 1.000000, [cartographer_node-5] use_nonmonotonic_steps = false, [cartographer_node-5] }, [cartographer_node-5] }, [cartographer_node-5] use_imu_based = false, [cartographer_node-5] }, [cartographer_node-5] real_time_correlative_scan_matcher = { [cartographer_node-5] angular_search_window = 0.349066, [cartographer_node-5] linear_search_window = 0.100000, [cartographer_node-5] rotation_delta_cost_weight = 0.100000, [cartographer_node-5] translation_delta_cost_weight = 10.000000, [cartographer_node-5] }, [cartographer_node-5] submaps = { [cartographer_node-5] grid_options_2d = { [cartographer_node-5] grid_type = "PROBABILITY_GRID", [cartographer_node-5] resolution = 0.050000, [cartographer_node-5] }, [cartographer_node-5] num_range_data = 35.000000, [cartographer_node-5] range_data_inserter = { [cartographer_node-5] probability_grid_range_data_inserter = { [cartographer_node-5] hit_probability = 0.550000, [cartographer_node-5] insert_free_space = true, [cartographer_node-5] miss_probability = 0.490000, [cartographer_node-5] }, [cartographer_node-5] range_data_inserter_type = "PROBABILITY_GRID_INSERTER_2D", [cartographer_node-5] tsdf_range_data_inserter = { [cartographer_node-5] maximum_weight = 10.000000, [cartographer_node-5] normal_estimation_options = { [cartographer_node-5] num_normal_samples = 4.000000, [cartographer_node-5] sample_radius = 0.500000, [cartographer_node-5] }, [cartographer_node-5] project_sdf_distance_to_scan_normal = true, [cartographer_node-5] truncation_distance = 0.300000, [cartographer_node-5] update_free_space = false, [cartographer_node-5] update_weight_angle_scan_normal_to_ray_kernel_bandwidth = 0.500000, [cartographer_node-5] update_weight_distance_cell_to_hit_kernel_bandwidth = 0.500000, [cartographer_node-5] update_weight_range_exponent = 0.000000, [cartographer_node-5] }, [cartographer_node-5] }, [cartographer_node-5] }, [cartographer_node-5] use_imu_data = true, [cartographer_node-5] use_online_correlative_scan_matching = true, [cartographer_node-5] voxel_filter_size = 0.025000, [cartographer_node-5] }, [cartographer_node-5] trajectory_builder_3d = { [cartographer_node-5] ceres_scan_matcher = { [cartographer_node-5] ceres_solver_options = { [cartographer_node-5] max_num_iterations = 12.000000, [cartographer_node-5] num_threads = 1.000000, [cartographer_node-5] use_nonmonotonic_steps = false, [cartographer_node-5] }, [cartographer_node-5] intensity_cost_function_options_0 = { [cartographer_node-5] huber_scale = 0.300000, [cartographer_node-5] intensity_threshold = 40.000000, [cartographer_node-5] weight = 0.500000, [cartographer_node-5] }, [cartographer_node-5] occupied_space_weight_0 = 1.000000, [cartographer_node-5] occupied_space_weight_1 = 6.000000, [cartographer_node-5] only_optimize_yaw = false, [cartographer_node-5] rotation_weight = 400.000000, [cartographer_node-5] translation_weight = 5.000000, [cartographer_node-5] }, [cartographer_node-5] high_resolution_adaptive_voxel_filter = { [cartographer_node-5] max_length = 2.000000, [cartographer_node-5] max_range = 15.000000, [cartographer_node-5] min_num_points = 150.000000, [cartographer_node-5] }, [cartographer_node-5] imu_gravity_time_constant = 10.000000, [cartographer_node-5] low_resolution_adaptive_voxel_filter = { [cartographer_node-5] max_length = 4.000000, [cartographer_node-5] max_range = 60.000000, [cartographer_node-5] min_num_points = 200.000000, [cartographer_node-5] }, [cartographer_node-5] max_range = 60.000000, [cartographer_node-5] min_range = 1.000000, [cartographer_node-5] motion_filter = { [cartographer_node-5] max_angle_radians = 0.004000, [cartographer_node-5] max_distance_meters = 0.100000, [cartographer_node-5] max_time_seconds = 0.500000, [cartographer_node-5] }, [cartographer_node-5] num_accumulated_range_data = 1.000000, [cartographer_node-5] pose_extrapolator = { [cartographer_node-5] constant_velocity = { [cartographer_node-5] imu_gravity_time_constant = 10.000000, [cartographer_node-5] pose_queue_duration = 0.001000, [cartographer_node-5] }, [cartographer_node-5] imu_based = { [cartographer_node-5] gravity_constant = 9.806000, [cartographer_node-5] imu_acceleration_weight = 1.000000, [cartographer_node-5] imu_rotation_weight = 1.000000, [cartographer_node-5] odometry_rotation_weight = 1.000000, [cartographer_node-5] odometry_translation_weight = 1.000000, [cartographer_node-5] pose_queue_duration = 5.000000, [cartographer_node-5] pose_rotation_weight = 1.000000, [cartographer_node-5] pose_translation_weight = 1.000000, [cartographer_node-5] solver_options = { [cartographer_node-5] max_num_iterations = 10.000000, [cartographer_node-5] num_threads = 1.000000, [cartographer_node-5] use_nonmonotonic_steps = false, [cartographer_node-5] }, [cartographer_node-5] }, [cartographer_node-5] use_imu_based = false, [cartographer_node-5] }, [cartographer_node-5] real_time_correlative_scan_matcher = { [cartographer_node-5] angular_search_window = 0.017453, [cartographer_node-5] linear_search_window = 0.150000, [cartographer_node-5] rotation_delta_cost_weight = 0.100000, [cartographer_node-5] translation_delta_cost_weight = 0.100000, [cartographer_node-5] }, [cartographer_node-5] rotational_histogram_size = 120.000000, [cartographer_node-5] submaps = { [cartographer_node-5] high_resolution = 0.100000, [cartographer_node-5] high_resolution_max_range = 20.000000, [cartographer_node-5] low_resolution = 0.450000, [cartographer_node-5] num_range_data = 160.000000, [cartographer_node-5] range_data_inserter = { [cartographer_node-5] hit_probability = 0.550000, [cartographer_node-5] intensity_threshold = 40.000000, [cartographer_node-5] miss_probability = 0.490000, [cartographer_node-5] num_free_space_voxels = 2.000000, [cartographer_node-5] }, [cartographer_node-5] }, [cartographer_node-5] use_intensities = false, [cartographer_node-5] use_online_correlative_scan_matching = false, [cartographer_node-5] voxel_filter_size = 0.150000, [cartographer_node-5] }, [cartographer_node-5] } [cartographer_node-5] [FATAL] [1753622779.626704366] [cartographer logger]: F0727 21:26:19.000000 2612 lua_parameter_dictionary.cc:399] Check failed: HasKey(key) Key 'collate_landmarks' not in dictionary: [cartographer_node-5] { [cartographer_node-5] collate_fixed_frame = true, [cartographer_node-5] trajectory_builder_2d = { [cartographer_node-5] adaptive_voxel_filter = { [cartographer_node-5] max_length = 0.500000, [cartographer_node-5] max_range = 50.000000, [cartographer_node-5] min_num_points = 200.000000, [cartographer_node-5] }, [cartographer_node-5] ceres_scan_matcher = { [cartographer_node-5] ceres_solver_options = { [cartographer_node-5] max_num_iterations = 20.000000, [cartographer_node-5] num_threads = 1.000000, [cartographer_node-5] use_nonmonotonic_steps = false, [cartographer_node-5] }, [cartographer_node-5] occupied_space_weight = 1.000000, [cartographer_node-5] rotation_weight = 40.000000, [cartographer_node-5] translation_weight = 10.000000, [cartographer_node-5] }, [cartographer_node-5] imu_gravity_time_constant = 10.000000, [cartographer_node-5] loop_closure_adaptive_voxel_filter = { [cartographer_node-5] max_length = 0.900000, [cartographer_node-5] max_range = 50.000000, [cartographer_node-5] min_num_points = 100.000000, [cartographer_node-5] }, [cartographer_node-5] max_range = 8.000000, [cartographer_node-5] max_z = 2.000000, [cartographer_node-5] min_range = 0.300000, [cartographer_node-5] min_z = -0.800000, [cartographer_node-5] missing_data_ray_length = 1.000000, [cartographer_node-5] motion_filter = { [cartographer_node-5] max_angle_radians = 0.017453, [cartographer_node-5] max_distance_meters = 0.200000, [cartographer_node-5] max_time_seconds = 5.000000, [cartographer_node-5] }, [cartographer_node-5] num_accumulated_range_data = 1.000000, [cartographer_node-5] pose_extrapolator = { [cartographer_node-5] constant_velocity = { [cartographer_node-5] imu_gravity_time_constant = 10.000000, [cartographer_node-5] pose_queue_duration = 0.001000, [cartographer_node-5] }, [cartographer_node-5] imu_based = { [cartographer_node-5] gravity_constant = 9.806000, [cartographer_node-5] imu_acceleration_weight = 1.000000, [cartographer_node-5] imu_rotation_weight = 1.000000, [cartographer_node-5] odometry_rotation_weight = 1.000000, [cartographer_node-5] odometry_translation_weight = 1.000000, [cartographer_node-5] pose_queue_duration = 5.000000, [cartographer_node-5] pose_rotation_weight = 1.000000, [cartographer_node-5] pose_translation_weight = 1.000000, [cartographer_node-5] solver_options = { [cartographer_node-5] max_num_iterations = 10.000000, [cartographer_node-5] num_threads = 1.000000, [cartographer_node-5] use_nonmonotonic_steps = false, [cartographer_node-5] }, [cartographer_node-5] }, [cartographer_node-5] use_imu_based = false, [cartographer_node-5] }, [cartographer_node-5] real_time_correlative_scan_matcher = { [cartographer_node-5] angular_search_window = 0.349066, [cartographer_node-5] linear_search_window = 0.100000, [cartographer_node-5] rotation_delta_cost_weight = 0.100000, [cartographer_node-5] translation_delta_cost_weight = 10.000000, [cartographer_node-5] }, [cartographer_node-5] submaps = { [cartographer_node-5] grid_options_2d = { [cartographer_node-5] grid_type = "PROBABILITY_GRID", [cartographer_node-5] resolution = 0.050000, [cartographer_node-5] }, [cartographer_node-5] num_range_data = 35.000000, [cartographer_node-5] range_data_inserter = { [cartographer_node-5] probability_grid_range_data_inserter = { [cartographer_node-5] hit_probability = 0.550000, [cartographer_node-5] insert_free_space = true, [cartographer_node-5] miss_probability = 0.490000, [cartographer_node-5] }, [cartographer_node-5] range_data_inserter_type = "PROBABILITY_GRID_INSERTER_2D", [cartographer_node-5] tsdf_range_data_inserter = { [cartographer_node-5] maximum_weight = 10.000000, [cartographer_node-5] normal_estimation_options = { [cartographer_node-5] num_normal_samples = 4.000000, [cartographer_node-5] sample_radius = 0.500000, [cartographer_node-5] }, [cartographer_node-5] project_sdf_distance_to_scan_normal = true, [cartographer_node-5] truncation_distance = 0.300000, [cartographer_node-5] update_free_space = false, [cartographer_node-5] update_weight_angle_scan_normal_to_ray_kernel_bandwidth = 0.500000, [cartographer_node-5] update_weight_distance_cell_to_hit_kernel_bandwidth = 0.500000, [cartographer_node-5] update_weight_range_exponent = 0.000000, [cartographer_node-5] }, [cartographer_node-5] }, [cartographer_node-5] }, [cartographer_node-5] use_imu_data = true, [cartographer_node-5] use_online_correlative_scan_matching = true, [cartographer_node-5] voxel_filter_size = 0.025000, [cartographer_node-5] }, [cartographer_node-5] trajectory_builder_3d = { [cartographer_node-5] ceres_scan_matcher = { [cartographer_node-5] ceres_solver_options = { [cartographer_node-5] max_num_iterations = 12.000000, [cartographer_node-5] num_threads = 1.000000, [cartographer_node-5] use_nonmonotonic_steps = false, [cartographer_node-5] }, [cartographer_node-5] intensity_cost_function_options_0 = { [cartographer_node-5] huber_scale = 0.300000, [cartographer_node-5] intensity_threshold = 40.000000, [cartographer_node-5] weight = 0.500000, [cartographer_node-5] }, [cartographer_node-5] occupied_space_weight_0 = 1.000000, [cartographer_node-5] occupied_space_weight_1 = 6.000000, [cartographer_node-5] only_optimize_yaw = false, [cartographer_node-5] rotation_weight = 400.000000, [cartographer_node-5] translation_weight = 5.000000, [cartographer_node-5] }, [cartographer_node-5] high_resolution_adaptive_voxel_filter = { [cartographer_node-5] max_length = 2.000000, [cartographer_node-5] max_range = 15.000000, [cartographer_node-5] min_num_points = 150.000000, [cartographer_node-5] }, [cartographer_node-5] imu_gravity_time_constant = 10.000000, [cartographer_node-5] low_resolution_adaptive_voxel_filter = { [cartographer_node-5] max_length = 4.000000, [cartographer_node-5] max_range = 60.000000, [cartographer_node-5] min_num_points = 200.000000, [cartographer_node-5] }, [cartographer_node-5] max_range = 60.000000, [cartographer_node-5] min_range = 1.000000, [cartographer_node-5] motion_filter = { [cartographer_node-5] max_angle_radians = 0.004000, [cartographer_node-5] max_distance_meters = 0.100000, [cartographer_node-5] max_time_seconds = 0.500000, [cartographer_node-5] }, [cartographer_node-5] num_accumulated_range_data = 1.000000, [cartographer_node-5] pose_extrapolator = { [cartographer_node-5] constant_velocity = { [cartographer_node-5] imu_gravity_time_constant = 10.000000, [cartographer_node-5] pose_queue_duration = 0.001000, [cartographer_node-5] }, [cartographer_node-5] imu_based = { [cartographer_node-5] gravity_constant = 9.806000, [cartographer_node-5] imu_acceleration_weight = 1.000000, [cartographer_node-5] imu_rotation_weight = 1.000000, [cartographer_node-5] odometry_rotation_weight = 1.000000, [cartographer_node-5] odometry_translation_weight = 1.000000, [cartographer_node-5] pose_queue_duration = 5.000000, [cartographer_node-5] pose_rotation_weight = 1.000000, [cartographer_node-5] pose_translation_weight = 1.000000, [cartographer_node-5] solver_options = { [cartographer_node-5] max_num_iterations = 10.000000, [cartographer_node-5] num_threads = 1.000000, [cartographer_node-5] use_nonmonotonic_steps = false, [cartographer_node-5] }, [cartographer_node-5] }, [cartographer_node-5] use_imu_based = false, [cartographer_node-5] }, [cartographer_node-5] real_time_correlative_scan_matcher = { [cartographer_node-5] angular_search_window = 0.017453, [cartographer_node-5] linear_search_window = 0.150000, [cartographer_node-5] rotation_delta_cost_weight = 0.100000, [cartographer_node-5] translation_delta_cost_weight = 0.100000, [cartographer_node-5] }, [cartographer_node-5] rotational_histogram_size = 120.000000, [cartographer_node-5] submaps = { [cartographer_node-5] high_resolution = 0.100000, [cartographer_node-5] high_resolution_max_range = 20.000000, [cartographer_node-5] low_resolution = 0.450000, [cartographer_node-5] num_range_data = 160.000000, [cartographer_node-5] range_data_inserter = { [cartographer_node-5] hit_probability = 0.550000, [cartographer_node-5] intensity_threshold = 40.000000, [cartographer_node-5] miss_probability = 0.490000, [cartographer_node-5] num_free_space_voxels = 2.000000, [cartographer_node-5] }, [cartographer_node-5] }, [cartographer_node-5] use_intensities = false, [cartographer_node-5] use_online_correlative_scan_matching = false, [cartographer_node-5] voxel_filter_size = 0.150000, [cartographer_node-5] }, [cartographer_node-5] } [cartographer_node-5] *** Check failure stack trace: *** [cartographer_node-5] @ 0xffff861dd41c google::LogMessage::Fail() [cartographer_node-5] @ 0xffff861e46d0 google::LogMessage::SendToLog() [cartographer_node-5] @ 0xffff861dd0f4 google::LogMessage::Flush() [cartographer_node-5] @ 0xffff861deebc google::LogMessageFatal::~LogMessageFatal() [cartographer_node-5] @ 0xaaaadf20392c (unknown) [cartographer_node-5] @ 0xaaaadf20398c (unknown) [cartographer_node-5] @ 0xaaaadf203dc8 (unknown) [cartographer_node-5] @ 0xaaaadf2210a8 (unknown) [cartographer_node-5] @ 0xaaaadf1eaeec (unknown) [cartographer_node-5] @ 0xaaaadf14743c (unknown) [cartographer_node-5] @ 0xffff857c73fc (unknown) [cartographer_node-5] @ 0xffff857c74cc __libc_start_main [cartographer_node-5] @ 0xaaaadf14abf0 (unknown) [test01-3] Traceback (most recent call last): [test01-3] File "/home/wjs/.local/lib/python3.10/site-packages/serial/serialposix.py", line 322, in open [test01-3] self.fd = os.open(self.portstr, os.O_RDWR | os.O_NOCTTY | os.O_NONBLOCK) [test01-3] FileNotFoundError: [Errno 2] No such file or directory: '/dev/mcu_usb' [test01-3] [test01-3] During handling of the above exception, another exception occurred: [test01-3] [test01-3] Traceback (most recent call last): [test01-3] File "/home/wjs/Drone_Slam/install/fishbot_grapher/lib/fishbot_grapher/test01", line 33, in <module> [test01-3] sys.exit(load_entry_point('fishbot-grapher==0.0.0', 'console_scripts', 'test01')()) [test01-3] File "/home/wjs/Drone_Slam/build/fishbot_grapher/fishbot_grapher/test01.py", line 101, in main [test01-3] tf_subscriber = TFSubscriber() [test01-3] File "/home/wjs/Drone_Slam/build/fishbot_grapher/fishbot_grapher/test01.py", line 20, in __init__ [test01-3] self.ser = serial.Serial("/dev/mcu_usb", 115200) [test01-3] File "/home/wjs/.local/lib/python3.10/site-packages/serial/serialutil.py", line 244, in __init__ [test01-3] self.open() [test01-3] File "/home/wjs/.local/lib/python3.10/site-packages/serial/serialposix.py", line 325, in open [test01-3] raise SerialException(msg.errno, "could not open port {}: {}".format(self._port, msg)) [test01-3] serial.serialutil.SerialException: [Errno 2] could not open port /dev/mcu_usb: [Errno 2] No such file or directory: '/dev/mcu_usb' [wit_ros2_imu-2] [INFO] [1753622781.380078547] [imu]: Serial port opening failure [ERROR] [test01-3]: process has died [pid 2608, exit code 1, cmd '/home/wjs/Drone_Slam/install/fishbot_grapher/lib/fishbot_grapher/test01 --ros-args']. [ERROR] [cartographer_node-5]: process has died [pid 2612, exit code -6, cmd '/opt/ros/humble/lib/cartographer_ros/cartographer_node -configuration_directory /home/wjs/Drone_Slam/install/fishbot_grapher/share/fishbot_grapher/config -configuration_basename test02.lua --ros-args -r __node:=cartographer_node --params-file /tmp/launch_params_clup20by'].
最新发布
07-28
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值