error: (-215:Assert ion failed) p.checkVector(2, CV_32S) >= 0 in function 'cv::po lylines'

时间: 2023-08-14 13:58:52 浏览: 137
这个错误通常出现在使用OpenCV库中的cv::polylines函数时。它表示输入的点坐标数据类型不正确或不满足要求。该函数要求输入的点坐标为一个整数型的二维向量,每个点的坐标为一个二维整数向量。 要解决这个错误,您可以检查以下几个方面: 1. 确保传递给cv::polylines函数的点坐标数据类型是CV_32S类型。可以使用cv::Mat::type()方法来检查数据类型。 2. 确保传递给cv::polylines函数的点坐标数据是一个二维整数型向量。您可以使用cv::Point或cv::Point2i来表示点坐标,并将这些点存储在一个std::vector<cv::Point>或std::vector<cv::Point2i>中。 3. 检查传递给cv::polylines函数的点坐标是否满足函数的要求。例如,确保点坐标的数量符合要求,并且每个点的坐标值在图像范围内。 通过检查以上几个方面,您应该能够解决该错误。如果问题仍然存在,请提供更多的代码和上下文信息,以便我能够帮助您更好地解决问题。
相关问题

User def __init__(self, primary_indices, secondary_indices, batch_size, secondary_batch_size): self.primary_indices = primary_indices self.secondary_indices = secondary_indices self.secondary_batch_size = secondary_batch_size self.primary_batch_size = batch_size - secondary_batch_size assert len(self.primary_indices) >= self.primary_batch_size > 0 assert len(self.secondary_indices) >= self.secondary_batch_size > 0代码解释

这段代码是一个Python类的构造函数,用于初始化对象的属性值。该类包含四个参数: - primary_indices: 主要索引,是一个列表类型。 - secondary_indices: 次要索引,也是一个列表类型。 - batch_size: 批次大小,是一个整数类型。 - secondary_batch_size: 次要批次大小,也是一个整数类型。 在初始化对象时,会将以上四个参数传入构造函数中,并创建以下四个属性: - self.primary_indices:用于存储主要索引。 - self.secondary_indices:用于存储次要索引。 - self.secondary_batch_size:用于存储次要批次大小。 - self.primary_batch_size:用于存储主要批次大小,其值为批次大小减去次要批次大小。 为了确保参数的合法性,代码中使用了两个assert语句进行断言,如果不满足条件,会抛出异常。第一个断言用于判断主要批次大小是否在主要索引的长度范围内,且大于0;第二个断言用于判断次要批次大小是否在次要索引的长度范围内,且大于0。

UnauthorizedError Traceback (most recent call last) Cell In[162], line 11 9 # 获取上个月的天气情况 10 mgr = owm.weather_manager() ---> 11 observation = mgr.weather_at_place('上海') # 这里以北京为例 12 date_obj = datetime.datetime(last_month.year, last_month.month, 1) 13 one_call = mgr.one_call(lat=observation.weather.location.lat, lon=observation.weather.location.lon, dt=date_obj.timestamp(), exclude='current,minutely,hourly,alerts') File ~/opt/anaconda3/lib/python3.9/site-packages/pyowm/weatherapi25/weather_manager.py:53, in WeatherManager.weather_at_place(self, name) 51 assert isinstance(name, str), "Value must be a string" 52 params = {'q': name} ---> 53 _, json_data = self.http_client.get_json(OBSERVATION_URI, params=params) 54 return observation.Observation.from_dict(json_data) File ~/opt/anaconda3/lib/python3.9/site-packages/pyowm/commons/http_client.py:158, in HttpClient.get_json(self, path, params, headers) 156 except requests.exceptions.Timeout: 157 raise exceptions.TimeoutError('API call timeouted') --> 158 HttpClient.check_status_code(resp.status_code, resp.text) 159 try: 160 return resp.status_code, resp.json() File ~/opt/anaconda3/lib/python3.9/site-packages/pyowm/commons/http_client.py:313, in HttpClient.check_status_code(cls, status_code, payload) 311 raise exceptions.APIRequestError(payload) 312 elif status_code == 401: --> 313 raise exceptions.UnauthorizedError('Invalid API Key provided') 314 elif status_code == 404: 315 raise exceptions.NotFoundError('Unable to find the resource')解释下是什么原因的报错

这个报错是因为你提供的OpenWeatherMap API Key无效或者过期了。在OpenWeatherMap的API访问中,API Key是必须的,如果API Key无效或者过期,将无法访问OpenWeatherMap API。 请检查你的API Key是否正确并且有效。你可以在OpenWeatherMap的官方网站上登录账户并获取新的API Key。 另外,如果你确定API Key是正确的,但是仍然出现这个报错,可能是因为你的API Key没有足够的权限或者OpenWeatherMap的API出现了故障。你可以等待一段时间再试,或者联系OpenWeatherMap的支持团队寻求帮助。
阅读全文

相关推荐

生成torch代码:class ConcreteAutoencoderFeatureSelector(): def __init__(self, K, output_function, num_epochs=300, batch_size=None, learning_rate=0.001, start_temp=10.0, min_temp=0.1, tryout_limit=1): self.K = K self.output_function = output_function self.num_epochs = num_epochs self.batch_size = batch_size self.learning_rate = learning_rate self.start_temp = start_temp self.min_temp = min_temp self.tryout_limit = tryout_limit def fit(self, X, Y=None, val_X=None, val_Y=None): if Y is None: Y = X assert len(X) == len(Y) validation_data = None if val_X is not None and val_Y is not None: assert len(val_X) == len(val_Y) validation_data = (val_X, val_Y) if self.batch_size is None: self.batch_size = max(len(X) // 256, 16) num_epochs = self.num_epochs steps_per_epoch = (len(X) + self.batch_size - 1) // self.batch_size for i in range(self.tryout_limit): K.set_learning_phase(1) inputs = Input(shape=X.shape[1:]) alpha = math.exp(math.log(self.min_temp / self.start_temp) / (num_epochs * steps_per_epoch)) self.concrete_select = ConcreteSelect(self.K, self.start_temp, self.min_temp, alpha, name='concrete_select') selected_features = self.concrete_select(inputs) outputs = self.output_function(selected_features) self.model = Model(inputs, outputs) self.model.compile(Adam(self.learning_rate), loss='mean_squared_error') print(self.model.summary()) stopper_callback = StopperCallback() hist = self.model.fit(X, Y, self.batch_size, num_epochs, verbose=1, callbacks=[stopper_callback], validation_data=validation_data) # , validation_freq = 10) if K.get_value(K.mean( K.max(K.softmax(self.concrete_select.logits, axis=-1)))) >= stopper_callback.mean_max_target: break num_epochs *= 2 self.probabilities = K.get_value(K.softmax(self.model.get_layer('concrete_select').logits)) self.indices = K.get_value(K.argmax(self.model.get_layer('concrete_select').logits)) return self def get_indices(self): return K.get_value(K.argmax(self.model.get_layer('concrete_select').logits)) def get_mask(self): return K.get_value(K.sum(K.one_hot(K.argmax(self.model.get_layer('concrete_select').logits), self.model.get_layer('concrete_select').logits.shape[1]), axis=0)) def transform(self, X): return X[self.get_indices()] def fit_transform(self, X, y): self.fit(X, y) return self.transform(X) def get_support(self, indices=False): return self.get_indices() if indices else self.get_mask() def get_params(self): return self.model

import torch, os, cv2 from model.model import parsingNet from utils.common import merge_config from utils.dist_utils import dist_print import torch import scipy.special, tqdm import numpy as np import torchvision.transforms as transforms from data.dataset import LaneTestDataset from data.constant import culane_row_anchor, tusimple_row_anchor if __name__ == "__main__": torch.backends.cudnn.benchmark = True args, cfg = merge_config() dist_print('start testing...') assert cfg.backbone in ['18','34','50','101','152','50next','101next','50wide','101wide'] if cfg.dataset == 'CULane': cls_num_per_lane = 18 elif cfg.dataset == 'Tusimple': cls_num_per_lane = 56 else: raise NotImplementedError net = parsingNet(pretrained = False, backbone=cfg.backbone,cls_dim = (cfg.griding_num+1,cls_num_per_lane,4), use_aux=False).cuda() # we dont need auxiliary segmentation in testing state_dict = torch.load(cfg.test_model, map_location='cpu')['model'] compatible_state_dict = {} for k, v in state_dict.items(): if 'module.' in k: compatible_state_dict[k[7:]] = v else: compatible_state_dict[k] = v net.load_state_dict(compatible_state_dict, strict=False) net.eval() img_transforms = transforms.Compose([ transforms.Resize((288, 800)), transforms.ToTensor(), transforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225)), ]) if cfg.dataset == 'CULane': splits = ['test0_normal.txt', 'test1_crowd.txt', 'test2_hlight.txt', 'test3_shadow.txt', 'test4_noline.txt', 'test5_arrow.txt', 'test6_curve.txt', 'test7_cross.txt', 'test8_night.txt'] datasets = [LaneTestDataset(cfg.data_root,os.path.join(cfg.data_root, 'list/test_split/'+split),img_transform = img_transforms) for split in splits] img_w, img_h = 1640, 590 row_anchor = culane_row_anchor elif cfg.dataset == 'Tusimple': splits = ['test.txt'] datasets = [LaneTestDataset(cfg.data_root,os.path.join(cfg.data_root, split),img_transform = img_transforms) for split in splits] img_w, img_h = 1280, 720 row_anchor = tusimple_row_anchor else: raise NotImplementedError for split, dataset in zip(splits, datasets): loader = torch.utils.data.DataLoader(dataset, batch_size=1, shuffle = False, num_workers=1) fourcc = cv2.VideoWriter_fourcc(*'MJPG') print(split[:-3]+'avi') vout = cv2.VideoWriter(split[:-3]+'avi', fourcc , 30.0, (img_w, img_h)) for i, data in enumerate(tqdm.tqdm(loader)): imgs, names = data imgs = imgs.cuda() with torch.no_grad(): out = net(imgs) col_sample = np.linspace(0, 800 - 1, cfg.griding_num) col_sample_w = col_sample[1] - col_sample[0] out_j = out[0].data.cpu().numpy() out_j = out_j[:, ::-1, :] prob = scipy.special.softmax(out_j[:-1, :, :], axis=0) idx = np.arange(cfg.griding_num) + 1 idx = idx.reshape(-1, 1, 1) loc = np.sum(prob * idx, axis=0) out_j = np.argmax(out_j, axis=0) loc[out_j == cfg.griding_num] = 0 out_j = loc # import pdb; pdb.set_trace() vis = cv2.imread(os.path.join(cfg.data_root,names[0])) for i in range(out_j.shape[1]): if np.sum(out_j[:, i] != 0) > 2: for k in range(out_j.shape[0]): if out_j[k, i] > 0: ppp = (int(out_j[k, i] * col_sample_w * img_w / 800) - 1, int(img_h * (row_anchor[cls_num_per_lane-1-k]/288)) - 1 ) cv2.circle(vis,ppp,5,(0,255,0),-1) vout.write(vis) vout.release()

try: import thop except ImportError: thop = None logger = logging.getLogger(__name__) @contextmanager def torch_distributed_zero_first(local_rank: int): if local_rank not in [-1, 0]: torch.distributed.barrier() yield if local_rank == 0: torch.distributed.barrier() def init_torch_seeds(seed=0): torch.manual_seed(seed) if seed == 0: cudnn.benchmark, cudnn.deterministic = False, True else: cudnn.benchmark, cudnn.deterministic = True, False def select_device(device='', batch_size=None): s = f'YOLOv5 🚀 {git_describe() or date_modified()} torch {torch.__version__} ' cpu = device.lower() == 'cpu' if cpu: os.environ['CUDA_VISIBLE_DEVICES'] = '-1' elif device: # non-cpu device requested os.environ['CUDA_VISIBLE_DEVICES'] = device assert torch.cuda.is_available(), f'CUDA unavailable, invalid device {device} requested' cuda = not cpu and torch.cuda.is_available() if cuda: n = torch.cuda.device_count() if n > 1 and batch_size: # check that batch_size is compatible with device_count assert batch_size % n == 0, f'batch-size {batch_size} not multiple of GPU count {n}' space = ' ' * len(s) for i, d in enumerate(device.split(',') if device else range(n)): p = torch.cuda.get_device_properties(i) s += f"{'' if i == 0 else space}CUDA:{d} ({p.name}, {p.total_memory / 1024 ** 2}MB)\n" s += 'CPU\n' logger.info(s.encode().decode('ascii', 'ignore') if platform.system() == 'Windows' else s) # emoji-safe return torch.device('cuda:0' if cuda else 'cpu') def time_synchronized(): if torch.cuda.is_available(): torch.cuda.synchronize() return time.time()

ValueError Traceback (most recent call last) Cell In[29], line 91 88 model.summary() 89 #模型训练 ---> 91 history = model.fit( 92 normed_train_data, train_labels, 93 epochs=100, validation_split=0.2, verbose=0) #verbose=表示不输出训练记录 94 #输出训练的各项指标值 95 hist = pd.DataFrame(history.history) File ~\anaconda3\lib\site-packages\keras\utils\traceback_utils.py:70, in filter_traceback.<locals>.error_handler(*args, **kwargs) 67 filtered_tb = _process_traceback_frames(e.__traceback__) 68 # To get the full stack trace, call: 69 # tf.debugging.disable_traceback_filtering() ---> 70 raise e.with_traceback(filtered_tb) from None 71 finally: 72 del filtered_tb File ~\AppData\Local\Temp\__autograph_generated_file1dq9vkey.py:15, in outer_factory.<locals>.inner_factory.<locals>.tf__train_function(iterator) 13 try: 14 do_return = True ---> 15 retval_ = ag__.converted_call(ag__.ld(step_function), (ag__.ld(self), ag__.ld(iterator)), None, fscope) 16 except: 17 do_return = False ValueError: in user code: File "C:\Users\lenovo\anaconda3\lib\site-packages\keras\engine\training.py", line 1284, in train_function * return step_function(self, iterator) File "C:\Users\lenovo\anaconda3\lib\site-packages\keras\engine\training.py", line 1268, in step_function ** outputs = model.distribute_strategy.run(run_step, args=(data,)) File "C:\Users\lenovo\anaconda3\lib\site-packages\keras\engine\training.py", line 1249, in run_step ** outputs = model.train_step(data) File "C:\Users\lenovo\anaconda3\lib\site-packages\keras\engine\training.py", line 1050, in train_step y_pred = self(x, training=True) File "C:\Users\lenovo\anaconda3\lib\site-packages\keras\utils\traceback_utils.py", line 70, in error_handler raise e.with_traceback(filtered_tb) from None File "C:\Users\lenovo\anaconda3\lib\site-packages\keras\engine\input_spec.py", line 298, in assert_input_compatibility raise ValueError( ValueError: Input 0 of layer "sequential_21" is incompatible with the layer: expected shape=(None, 14), found shape=(32, 15)

最新推荐

recommend-type

python的uds诊断相关接口

python的uds诊断相关接口
recommend-type

白色大气风格的旅行网站模板下载.zip

白色大气风格的旅行网站模板下载.zip
recommend-type

白色大气风格的模糊背景商务网站模板下载.zip

白色大气风格的模糊背景商务网站模板下载.zip
recommend-type

RStudio中集成Connections包以优化数据库连接管理

资源摘要信息:"connections:https" ### 标题解释 标题 "connections:https" 直接指向了数据库连接领域中的一个重要概念,即通过HTTP协议(HTTPS为安全版本)来建立与数据库的连接。在IT行业,特别是数据科学与分析、软件开发等领域,建立安全的数据库连接是日常工作的关键环节。此外,标题可能暗示了一个特定的R语言包或软件包,用于通过HTTP/HTTPS协议实现数据库连接。 ### 描述分析 描述中提到的 "connections" 是一个软件包,其主要目标是与R语言的DBI(数据库接口)兼容,并集成到RStudio IDE中。它使得R语言能够连接到数据库,尽管它不直接与RStudio的Connections窗格集成。这表明connections软件包是一个辅助工具,它简化了数据库连接的过程,但并没有改变RStudio的用户界面。 描述还提到connections包能够读取配置,并创建与RStudio的集成。这意味着用户可以在RStudio环境下更加便捷地管理数据库连接。此外,该包提供了将数据库连接和表对象固定为pins的功能,这有助于用户在不同的R会话中持续使用这些资源。 ### 功能介绍 connections包中两个主要的功能是 `connection_open()` 和可能被省略的 `c`。`connection_open()` 函数用于打开数据库连接。它提供了一个替代于 `dbConnect()` 函数的方法,但使用完全相同的参数,增加了自动打开RStudio中的Connections窗格的功能。这样的设计使得用户在使用R语言连接数据库时能有更直观和便捷的操作体验。 ### 安装说明 描述中还提供了安装connections包的命令。用户需要先安装remotes包,然后通过remotes包的`install_github()`函数安装connections包。由于connections包不在CRAN(综合R档案网络)上,所以需要使用GitHub仓库来安装,这也意味着用户将能够访问到该软件包的最新开发版本。 ### 标签解读 标签 "r rstudio pins database-connection connection-pane R" 包含了多个关键词: - "r" 指代R语言,一种广泛用于统计分析和图形表示的编程语言。 - "rstudio" 指代RStudio,一个流行的R语言开发环境。 - "pins" 指代R包pins,它可能与connections包一同使用,用于固定数据库连接和表对象。 - "database-connection" 指代数据库连接,即软件包要解决的核心问题。 - "connection-pane" 指代RStudio IDE中的Connections窗格,connections包旨在与之集成。 - "R" 代表R语言社区或R语言本身。 ### 压缩包文件名称列表分析 文件名称列表 "connections-master" 暗示了一个可能的GitHub仓库名称或文件夹名称。通常 "master" 分支代表了软件包或项目的稳定版或最新版,是大多数用户应该下载和使用的版本。 ### 总结 综上所述,connections包是一个专为R语言和RStudio IDE设计的软件包,旨在简化数据库连接过程并提供与Connections窗格的集成。它允许用户以一种更为方便的方式打开和管理数据库连接,而不直接提供与Connections窗格的集成。connections包通过读取配置文件和固定连接对象,增强了用户体验。安装connections包需通过remotes包从GitHub获取最新开发版本。标签信息显示了connections包与R语言、RStudio、数据库连接以及R社区的紧密联系。
recommend-type

管理建模和仿真的文件

管理Boualem Benatallah引用此版本:布阿利姆·贝纳塔拉。管理建模和仿真。约瑟夫-傅立叶大学-格勒诺布尔第一大学,1996年。法语。NNT:电话:00345357HAL ID:电话:00345357https://theses.hal.science/tel-003453572008年12月9日提交HAL是一个多学科的开放存取档案馆,用于存放和传播科学研究论文,无论它们是否被公开。论文可以来自法国或国外的教学和研究机构,也可以来自公共或私人研究中心。L’archive ouverte pluridisciplinaire
recommend-type

Keil uVision5全面精通指南

# 摘要 Keil uVision5是一个集成开发环境,广泛应用于嵌入式系统的开发。本文从基础入门开始,详细介绍了Keil uVision5的项目管理、配置、编程实践、高级功能及技巧,并通过项目案例分析,深入阐述了其在实际开发中的应用。本篇论文特别注重于项目创建、目标配置、调试环境搭建、性能优化、脚本编程与自动化、高级调试技术,以及通过嵌入式操作系统集成和驱动开发流程的案例分析,展示了Keil uVision5的实用性和高效性。文章还展望了Keil uVision5的未来发展趋势,并提供了社区资源和学习渠道,为读者提供了一个全面掌握Keil uVision5的平台。 # 关键字 Keil u
recommend-type

flink提交给yarn19个全量同步MYsqlCDC的作业,flink的配置参数怎样设置

在Flink中,如果你需要将19个MySQL CDC(Change Data Capture)的全量同步作业提交到YARN上,你需要确保Flink集群和YARN进行了正确的集成,并配置了适当的参数。以下是可能涉及到的一些关键配置: 1. **并行度(Parallelism)**:每个作业的并行度应该设置得足够高,以便充分利用YARN提供的资源。例如,如果你有19个任务,你可以设置总并行度为19或者是一个更大的数,取决于集群规模。 ```yaml parallelism = 19 或者 根据实际资源调整 ``` 2. **YARN资源配置**:Flink通过`yarn.a
recommend-type

PHP博客旅游的探索之旅

资源摘要信息:"博客旅游" 博客旅游是一个以博客形式分享旅行经验和旅游信息的平台。随着互联网技术的发展和普及,博客作为一种个人在线日志的形式,已经成为人们分享生活点滴、专业知识、旅行体验等的重要途径。博客旅游正是结合了博客的个性化分享特点和旅游的探索性,让旅行爱好者可以记录自己的旅游足迹、分享旅游心得、提供目的地推荐和旅游攻略等。 在博客旅游中,旅行者可以是内容的创造者也可以是内容的消费者。作为创造者,旅行者可以通过博客记录下自己的旅行故事、拍摄的照片和视频、体验和评价各种旅游资源,如酒店、餐馆、景点等,还可以分享旅游小贴士、旅行日程规划等实用信息。作为消费者,其他潜在的旅行者可以通过阅读这些博客内容获得灵感、获取旅行建议,为自己的旅行做准备。 在技术层面,博客平台的构建往往涉及到多种编程语言和技术栈,例如本文件中提到的“PHP”。PHP是一种广泛使用的开源服务器端脚本语言,特别适合于网页开发,并可以嵌入到HTML中使用。使用PHP开发的博客旅游平台可以具有动态内容、用户交互和数据库管理等强大的功能。例如,通过PHP可以实现用户注册登录、博客内容的发布与管理、评论互动、图片和视频上传、博客文章的分类与搜索等功能。 开发一个功能完整的博客旅游平台,可能需要使用到以下几种PHP相关的技术和框架: 1. HTML/CSS/JavaScript:前端页面设计和用户交互的基础技术。 2. 数据库管理:如MySQL,用于存储用户信息、博客文章、评论等数据。 3. MVC框架:如Laravel或CodeIgniter,提供了一种组织代码和应用逻辑的结构化方式。 4. 服务器技术:如Apache或Nginx,作为PHP的运行环境。 5. 安全性考虑:需要实现数据加密、输入验证、防止跨站脚本攻击(XSS)等安全措施。 当创建博客旅游平台时,还需要考虑网站的可扩展性、用户体验、移动端适配、搜索引擎优化(SEO)等多方面因素。一个优质的博客旅游平台,不仅能够提供丰富的内容,还应该注重用户体验,包括页面加载速度、界面设计、内容的易于导航等。 此外,博客旅游平台还可以通过整合社交媒体功能,允许用户通过社交媒体账号登录、分享博客内容到社交网络,从而提升平台的互动性和可见度。 综上所述,博客旅游作为一个结合了旅行分享和在线日志的平台,对于旅行者来说,不仅是一个记录和分享旅行体验的地方,也是一个获取旅行信息、学习旅游知识的重要资源。而对于开发者来说,构建这样一个平台需要运用到多种技术和考虑多个技术细节,确保平台的功能性和用户体验。
recommend-type

"互动学习:行动中的多样性与论文攻读经历"

多样性她- 事实上SCI NCES你的时间表ECOLEDO C Tora SC和NCESPOUR l’Ingén学习互动,互动学习以行动为中心的强化学习学会互动,互动学习,以行动为中心的强化学习计算机科学博士论文于2021年9月28日在Villeneuve d'Asq公开支持马修·瑟林评审团主席法布里斯·勒菲弗尔阿维尼翁大学教授论文指导奥利维尔·皮耶昆谷歌研究教授:智囊团论文联合主任菲利普·普雷教授,大学。里尔/CRISTAL/因里亚报告员奥利维耶·西格德索邦大学报告员卢多维奇·德诺耶教授,Facebook /索邦大学审查员越南圣迈IMT Atlantic高级讲师邀请弗洛里安·斯特鲁布博士,Deepmind对于那些及时看到自己错误的人...3谢谢你首先,我要感谢我的两位博士生导师Olivier和Philippe。奥利维尔,"站在巨人的肩膀上"这句话对你来说完全有意义了。从科学上讲,你知道在这篇论文的(许多)错误中,你是我可以依
recommend-type

【单片机编程实战】:掌握流水灯与音乐盒同步控制的高级技巧

![单片机编程](https://static.mianbaoban-assets.eet-china.com/xinyu-images/MBXY-CR-48cf6abe199bab09d31c122e1f49cea4.png) # 摘要 单片机作为电子技术领域的基础组件,广泛应用于各类控制项目。本文从基础开始,详细探讨了单片机在流水灯和音乐盒项目中的应用原理,并分析了如何实现这两个功能的同步控制。通过对硬件和软件层面的深入剖析,本文提供了一系列实践操作和高级技巧,旨在提升流水灯与音乐盒同步控制的性能和效率。通过本研究,读者将能够更好地理解和掌握单片机在复杂控制系统中的应用,进而创新开发更多