VTK User’s Guide -11th edition 第03章-VTK系统概述(3)

2023-05-16


【本节对应原书中的第29页至第39页】

3.2创建VTK应用程序

本章内容包括利用Tcl,C++,Java和Python四种语言开发VTK应用程序的基本知识。阅读完引言后,你应该了解用你擅长的语言进行VTK开发的相关内容。为了指导你怎么去创建和运行一个简单的VTK程序,接下来内容都会针对不同的编程语言演示怎样使用Callback。

用户事件、观察者以及命令模式

Callback(又称用户方法UserMethod)采用Subject/Observer和Command设计模式进行设计。VTK中几乎所有的类都可以通过SetObserver()方法建立Callback。Observer观察者监听对象中的所有激活事件,一旦其中一个事件与其监听事件类型一致的话,则其相应的Command就会执行(如Callback)。例如,所有Filter在执行前都会激活StartEvent事件。如果为Filter添加一个Observer来监听StartEvent事件,那么每次Filter执行前,该Observer都会被调用响应Callback。下面的Tcl脚本中创建了一个vtkElevation的实例,并为添加一个Observer来监听StartEvent事件。当Observer监听到该事件时,则自动响应函数PrintStatus()。

[plain] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. proc PrintStatus {} {  
  2. puts “Starting to execute the elevation filter”  
  3. }  
  4. vtkElevationFilter foo  
  5. foo AddObserver StartEvent PrintStatus  

VTK支持的所有语言都可使用这种类型的函数(Callback)。接下来每个小节中都会给出一个简单的例子来说明如何使用它。关于用户方法的深入探讨请参考421页“Integratingwith The Windowing System”(与窗口系统的整合)(该章中还涉及了用户接口整合问题)。

我们建议从VTK自带的例子开始学习如何创建应用程序。这些例子在VTK源文件VTK\Examples目录下。目录中根据不同的主题进行细分,在每个主题目录中会根据不同的语言再分为不同的子目录。

 

Tcl

学习使用VTK创建应用程序时,Tcl脚本语言是最简单的语言之一。VTK安装完毕后,即可执行VTK自带的Tcl例子。Unix系统下,根据“Unix平台下安装VTK”一节介绍,编译VTK时需要选择支持Tcl。而Windows系统下只需要编译安装自解压目录即可,参考第10页“WindowsXP, Vista及以上版本平台下安装VTK”。

 

Windows:Windows系统下只需双击Tcl脚本文件即可执行(如本例中Cone.tcl)。如果双击没有反应的话,脚本中可能存在错误,或者是相应的Tcl文件与vtk.exe有错误。如果要进一步检测具体问题,首先需要运行vtk.exe程序,该程序在vtk启动菜单中可以找到。执行后,会弹出一个命令提示行的控制台窗口,在提示行中,键入“cd”命令定位到Tcl文件目录,如下:

[plain] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. % cd“ c:/VTK/Examples/Tutorial/Step1/Tcl”  

然后键入如下命令定位示例脚本:

[plain] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. %source Cone.tcl  

Tcl会执行该脚本,这时所有的错误或者警告信息会输出来。

 

Unix:Unix下Tcl开发可以通过运行Binary编译目录下(如VTK-bin/bin/VTK,VTK-Solaris/bin/VTK)的可执行文件(编译完成后),然后将脚本文件作为第一个参数输入,如下所示。

[plain] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. unixmachine> cd VTK/Examples/Tutorial/Step1/Tcl  
  2.   
  3. unixmachine> /home/ VTK-Solaris/bin/VTK Cone.tcl  

用户方法使用如前所述。Examples/Tutorial/Step2/Tcl/Cone2.tcl中有相关的使用示例。下面仅列出了其中的关键部分。

[plain] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. Proc mycallback {} {  
  2.   
  3.     Puts “Starting to render”  
  4.   
  5. }  
  6.   
  7.    
  8.   
  9. vtkRendererren1  
  10.   
  11. ren1AddObserver StartEvent mycallback  

你也可以直接给AddObserver()提供函数体。

[plain] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. vtkRenderer ren1  
  2.   
  3. ren1 AddObserver StartEvent {puts “Starting to render”}  

C++

相对于其他语言,C++应用程序体积更小,运行更快,而且容易部署安装。此外,采用C++语言开发VTK应用程序,你不需要编译额外的Tcl、Java和Python支持。本节中主要说明怎么在PC机上用MicrosoftVisual C++或者Unix下的编译器来用C++开发简单的VTK应用程序。

我们以Examples/Tutorial/Step1/Cxx下的Cone.cxx为例进行讲解。无论Windows平台还是Unix,都可以使用源代码编译版本或者是发布的可执行版本,两个版本都支持这些例子。

编译C++程序的第一步是利用CMake生成依赖于编译器的makefile或者是项目工程文件。Cone.txx目录下的CMakeLists.txt利用CMake的FindVTK和UseVTK模块来定位VTK目录并设置包含路径和链接库等。如果没有成功找到VTK的话,你需要手动设置CMake相关的参数并重新运行CMake。

[plain] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. PROJECT(Step1)  
  2.   
  3. FIND_PACKAGE(VTKREQUIRED)  
  4.   
  5. IF(NOTVTK_USE_RENDERING)  
  6.   
  7.   MESSAGE(FATAL_ERROR "Example${PROJECT_NAME} requires VTK_USE_RENDERING.")  
  8.   
  9. ENDIF(NOTVTK_USE_RENDERING)  
  10.   
  11. INCLUDE(${VTK_USE_FILE})  
  12.   
  13.   
  14. ADD_EXECUTABLE(ConeCone.cxx)  
  15.   
  16. TARGET_LINK_LIBRARIES(ConevtkRendering)  

MicrosoftVisual C++:用CMake对Cone.cxx配置完成后,启动MicrosoftVisual C++并载入生成的解决方案。当前.net版本下的解决方案名字是Cone.sln。根据需要选择Release或者Debug版本编译程序。如果想把将VTK整合到其他不采用CMake的工程中,可以直接拷贝该工程的设置到相应的工程中。

下面看一个Windows应用程序示例。其创建过程与上述例子基本相同,除了我们建立的是一个Windows窗口程序而不是控制台程序。大部分代码都是Windows开发者熟悉的标准Windows窗口语言。该例子在VTK/Examples/GUI/Win32/SimpleCxx/Win32Cone.cxx目录下。注意CMakeLists.txt文件中的一个重要变化是ADD_EXECUTABLE命令的WIN32参数。

[cpp] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #include "windows.h"  
  2.   
  3. #include "vtkConeSource.h"  
  4.   
  5. #include "vtkPolyDataMapper.h"  
  6.   
  7. #include "vtkRenderWindow.h"  
  8.   
  9. #include "vtkRenderWindowInteractor.h"  
  10.   
  11. #include "vtkRenderer.h"  
  12.   
  13.    
  14.   
  15. static HANDLE hinst;  
  16.   
  17. LRESULTCALLBACK WndProc(HWNDUINTWPARAMLPARAM);  
  18.   
  19.    
  20.   
  21. //define the vtk part as a simple c++ class  
  22.   
  23. class myVTKApp    
  24.   
  25. {  
  26.   
  27. public:  
  28.   
  29.   myVTKApp(HWND parent);      
  30.   
  31.   ~myVTKApp();  
  32.   
  33. private:  
  34.   
  35.   vtkRenderWindow *renWin;  
  36.   
  37.   vtkRenderer *renderer;  
  38.   
  39.   vtkRenderWindowInteractor *iren;  
  40.   
  41.   vtkConeSource *cone;  
  42.   
  43.   vtkPolyDataMapper *coneMapper;  
  44.   
  45.   vtkActor *coneActor;  
  46.   
  47. };  

程序开始包含进必须的VTK头文件。然后是两个原型声明,接下来定义了一个myVTKApp类。使用C++开发时,要尽量采用面向对象的编程方法,而不是像Tcl例子中的脚本语言样式。这里我们将VTK应用程序的组件封装到一个简单类中。

下面是myVTKApp类的构造函数。首先创建每个VTK对象并进行相应的设置,然后将各个组件对象连接形成可视化管线。除了vtkRenderWindow的代码外,其他都是很简洁的VTK代码。构造函数接收一个父窗口的HWND的句柄以便使父窗口包含VTK渲染窗口。然后利用vtkRenderWindow的SetParentId()函数设置父窗口,并创建自己的窗口作为父窗口的子窗口。

[cpp] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. myVTKApp::myVTKApp(HWNDhwnd)  
  2.   
  3. {  
  4.   
  5.   // Similar toExamples/Tutorial/Step1/Cxx/Cone.cxx  
  6.   
  7.   // We create the basic parts of a pipelineand connect them  
  8.   
  9.   this->renderer = vtkRenderer::New();  
  10.   
  11.   this->renWin = vtkRenderWindow::New();  
  12.   
  13.  this->renWin->AddRenderer(this->renderer);  
  14.   
  15.    
  16.   
  17.   // setup the parent window  
  18.   
  19.   this->renWin->SetParentId(hwnd);  
  20.   
  21.   this->iren =vtkRenderWindowInteractor::New();  
  22.   
  23.  this->iren->SetRenderWindow(this->renWin);  
  24.   
  25.    
  26.   
  27.   this->cone = vtkConeSource::New();  
  28.   
  29.   this->cone->SetHeight( 3.0 );  
  30.   
  31.   this->cone->SetRadius( 1.0 );  
  32.   
  33.   this->cone->SetResolution( 10 );  
  34.   
  35.   this->coneMapper =vtkPolyDataMapper::New();  
  36.   
  37.  this->coneMapper->SetInputConnection(this->cone->GetOutputPort());  
  38.   
  39.   this->coneActor = vtkActor::New();  
  40.   
  41.   this->coneActor->SetMapper(this->coneMapper);  
  42.   
  43.    
  44.   
  45.  this->renderer->AddActor(this->coneActor);  
  46.   
  47.  this->renderer->SetBackground(0.2,0.4,0.3);  
  48.   
  49.   this->renWin->SetSize(400,400);  
  50.   
  51.    
  52.   
  53.   // Finally we start the interactor so thatevent will be handled  
  54.   
  55.   this->renWin->Render();  
  56.   
  57. }  

析构函数中释放所有构造函数中创建的所有VTK对象。

[cpp] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. myVTKApp::~myVTKApp()  
  2.   
  3. {  
  4.   
  5.     renWin->Delete();  
  6.   
  7.     renderer->Delete();  
  8.   
  9.     iren->Delete();  
  10.   
  11.     cone->Delete();  
  12.   
  13.     coneMapper->Delete();  
  14.   
  15.     coneActor->Delete();  
  16.   
  17. }  

WinMain函数中都是标准的Windows编程语言,没有用到VTK引用。该应用程序中具有消息循环控制功能,消息处理由下面介绍的WinProc函数实现。

[cpp] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. int PASCAL WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,  
  2.   
  3.                     LPSTR /* lpszCmdParam */,int nCmdShow)  
  4.   
  5. {  
  6.   
  7.   static char szAppName[] ="Win32Cone";  
  8.   
  9.   HWND       hwnd ;  
  10.   
  11.   MSG        msg ;  
  12.   
  13.   WNDCLASS   wndclass ;  
  14.   
  15.    
  16.   
  17.   if (!hPrevInstance)  
  18.   
  19.     {  
  20.   
  21.     wndclass.style         = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;  
  22.   
  23.     wndclass.lpfnWndProc   = WndProc ;  
  24.   
  25.     wndclass.cbClsExtra     = 0 ;  
  26.   
  27.     wndclass.cbWndExtra    = 0 ;  
  28.   
  29.     wndclass.hInstance     = hInstance;  
  30.   
  31.     wndclass.hIcon         = LoadIcon(NULL,IDI_APPLICATION);  
  32.   
  33.     wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW);          
  34.   
  35.     wndclass.lpszMenuName  = NULL;  
  36.   
  37.     wndclass.hbrBackground =(HBRUSH)GetStockObject(BLACK_BRUSH);  
  38.   
  39.     wndclass.lpszClassName = szAppName;  
  40.   
  41.     RegisterClass (&wndclass);  
  42.   
  43.     }  
  44.   
  45.    
  46.   
  47.   hinst = hInstance;  
  48.   
  49.   hwnd = CreateWindow ( szAppName,  
  50.   
  51.                         "DrawWindow",  
  52.   
  53.                         WS_OVERLAPPEDWINDOW,  
  54.   
  55.                         CW_USEDEFAULT,  
  56.   
  57.                         CW_USEDEFAULT,  
  58.   
  59.                         400,  
  60.   
  61.                         480,  
  62.   
  63.                         NULL,  
  64.   
  65.                         NULL,  
  66.   
  67.                         hInstance,  
  68.   
  69.                         NULL);  
  70.   
  71.   ShowWindow (hwnd, nCmdShow);  
  72.   
  73.   UpdateWindow (hwnd);  
  74.   
  75.   while (GetMessage (&msg, NULL, 0, 0))  
  76.   
  77.     {      
  78.   
  79.     TranslateMessage (&msg);  
  80.   
  81.     DispatchMessage (&msg);  
  82.   
  83.     }  
  84.   
  85.   return msg.wParam;  
  86.   
  87. }  


WinProc是一个简单的消息处理函数。对于一个完整的应用程序来说,它可能要比这个复杂的多,但是关键部分都是相同的。函数开始定义了一个myVTKApp实例的静态引用变量。当处理WM_CREATE消息时,我们创建了一个Exit按钮,然后创建myVTKApp实例并传入当前窗口的句柄。vtkRendererWindowInteractor会为vtkRendererWindow处理所有的消息,因此这里不需要处理消息。你很可能想添加代码来处理resizing消息,这样窗口的大小就可以随着用户界面的改变而自动调整。如果没有设置vtkRendererWindow的ParentId的话,vtkRendererWindow就作为一个顶层的独立窗口显示。其他的部分则没有变化。

[cpp] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. LRESULTCALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)  
  2.   
  3. {  
  4.   
  5.   static HWND ewin;  
  6.   
  7.   static myVTKApp *theVTKApp;  
  8.   
  9.    
  10.   
  11.   switch (message)  
  12.   
  13.     {  
  14.   
  15.     case WM_CREATE:  
  16.   
  17.       {  
  18.   
  19.       ewin =CreateWindow("button","Exit",  
  20.   
  21.                           WS_CHILD | WS_VISIBLE| SS_CENTER,                     
  22.   
  23.                           0,400,400,60,  
  24.   
  25.                           hwnd,(HMENU)2,  
  26.   
  27.                          (HINSTANCE)vtkGetWindowLong(hwnd,vtkGWL_HINSTANCE),  
  28.   
  29.                           NULL);  
  30.   
  31.       theVTKApp = new myVTKApp(hwnd);  
  32.   
  33.       return 0;  
  34.   
  35.       }  
  36.   
  37.        
  38.   
  39.     case WM_COMMAND:  
  40.   
  41.       switch (wParam)  
  42.   
  43.         {  
  44.   
  45.         case 2:  
  46.   
  47.           PostQuitMessage (0);  
  48.   
  49.           if (theVTKApp)  
  50.   
  51.             {  
  52.   
  53.             delete theVTKApp;  
  54.   
  55.             theVTKApp = NULL;  
  56.   
  57.             }  
  58.   
  59.           break;  
  60.   
  61.         }  
  62.   
  63.       return 0;  
  64.   
  65.        
  66.   
  67.     case WM_DESTROY:  
  68.   
  69.       PostQuitMessage (0);  
  70.   
  71.       if (theVTKApp)  
  72.   
  73.         {  
  74.   
  75.         delete theVTKApp;  
  76.   
  77.         theVTKApp = NULL;  
  78.   
  79.         }  
  80.   
  81.       return 0;  
  82.   
  83.     }  
  84.   
  85.   return DefWindowProc (hwnd, message, wParam,lParam);  
  86.   
  87. }  

Unix: Unix下主要通过运行CMake和make来创建应用程序。CMake生成一个makefile文件,该文件中设置了包含路径、链接路径(link lines)和依赖库等。然后make程序利用makefile文件编译应用程序,生成一个可执行文件。如果Cone.txx编译失败,则需要检查和改正代码中的错误。确保CMakeCache.txt文件中开始的变量值是有效的。如果可以编译,但是运行出错的话,则需要参考第二章中设置LD_LIBRARY_PATH变量。

C++中的用户方法:通过实例化vtkCommand的派生类,并重载Execute()函数,你可以添加自己的用户方法(利用Observer/Command设计模式)。下面例子截取自VTK/Examples/Tutorial/Step2/Cxx/Cone2.cxx。

[cpp] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. class vtkMyCallback : public vtkCommand  
  2.   
  3. {  
  4.   
  5. public:  
  6.   
  7.   static vtkMyCallback *New()  { return new vtkMyCallback; }  
  8.   
  9.   virtual void Execute(vtkObject *caller,unsigned longvoid*)  
  10.   
  11.     {  
  12.   
  13.       vtkRenderer *renderer =reinterpret_cast<vtkRenderer*>(caller);  
  14.   
  15.       cout <<renderer->GetActiveCamera()->GetPosition()[0] << " "  
  16.   
  17.            <<renderer->GetActiveCamera()->GetPosition()[1] << " "  
  18.   
  19.            <<renderer->GetActiveCamera()->GetPosition()[2] << "\n";  
  20.   
  21.     }  
  22.   
  23. };  

Execute()函数会传递一个不常使用的caller对象。当你的确需要调用caller时,你需要使用SafeDownCast函数将其转换为其实际的类型。例如:

[cpp] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. virtual void Execute (vtkObject *caller, unsigned longvoid *callData)  
  2.   
  3. {  
  4.   
  5.   vtkRenderer *ren = vtkRenderer::SafeDownCast(caller);  
  6.   
  7.   if (ren) { ren->SetBackground(0.2, 0.3,0.4); }  
  8.   
  9. }  

当创建了你的vtkCommand派生类对象时,你就可以添加一个Observer来监听某个事件。当事件发生时,就会通过Observer执行你的Command命令。如下所示。

[cpp] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. //Hereis where we setup the observer  
  2.   
  3. //wedo a new and ren1 will eventually free the observer  
  4.   
  5. vtkMyCallback*mol = vtkMyCallback::New();  
  6.   
  7. ren1->AddObserver(vtkCommand::StartEvent,mol);  

上面代码创建了一个myCallback实例,然后为ren1添加了一个Observer来监听StartEvent事件。当ren1开始渲染时,vtkMyCallback的Execute方法就会被调用。ren1被删除后,Callback对象也会相应的删除。

Java

创建Java应用程序,首先需要一个Java开发环境。本小节主要为Windows或者Unix下利用sun公司JDK1.3或者后续版本开发VTK应用程序提供指导。当JDK和VTK都成功安装后,你需要设置CLASSPATH环境变量来包含VTK类库。微软Windows系统下右击“我的电脑”图标,选择“属性”选项卡,然后选择“高级”tab页,点击“环境变量”按钮。然后添加一个CLASSPATH环境变量,设置值vtk.jar文件路径、Wrapping/java路径及当前路径。Windows下其值如“C:\vtk-bin\bin\vtk.jar;C:\vtk-bin\Wrapping/java;.”。Unix系统下CLASSPATH应设置如“/yourdisk/vtk-bin/bin/vtk.jar;/yourdisk/vtk-bin/Wrapping/java;.”。

接着是字节编译(ByteCompile)Java应用程序。对于新手可以尝试编译(用javac命令)VTK自带例子VTK/Examples/Tutorial/Step1/Java/Cone.java。编译完成后,通过java命令即可运行生成的应用程序。该程序绘制了一个旋转360度的圆锥,然后退出。以该例子作为起点,可以开始创建自己的应用程序了。

[java] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public void myCallback()  
  2.   
  3. {  
  4.   
  5.   System.out.println("Starting torender");  
  6.   
  7. }  

设置Callback需要三个参数。首先是你关心的事件,第二是类的实例,第三是调用的函数名。在本例中我们设置监听StartEvent事件以调用me(Cone2的实例)的方法myCallback。为了避免错误,确保myCallback函数是Cone2的成员函数(该例子源码见VTK/Examples/Tutorial/Step2/Java/cone2.java)。

[java] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. Cone2 me = new Cone2();  
  2.   
  3. ren1.AddObserver("StartEvent",me, "myCallback");  

Python

如果编译VTK时设置支持Python,那么编译后会生成一个vtkpython可执行文件。利用这个可执行文件,可以如下运行“Examples/Tutorial/Step1/Python/Cone.py”。

[python] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. vtkpython Cone.py  

以VTK自带的示例脚本作为参照来创建Python脚本会比较简单。用户方法通过定义一个函数并将其作为参数传入AddObserver来定义,如下:

[python] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. def myCallback(obj, event)  
  2.   
  3.    print "Starting to render"  
  4.   
  5. ren1.AddObserver("StartEvent",myCallback)  

完整的源代码见VTK/Examples/Tutorial/Step2/Python/Cone2.py。

3.3语言间的转换

VTK核心代码采用C++语言实现,然后用Tcl,Java和Python编程语言包装。这样在应用程序开发时,你可以有多种语言选择。语言选择主要依赖于个人的语言习惯,应用程序的特点,是否需要访问内部数据以及是否对性能有特殊要求。与其他语言相比,C++在访问内部数据结构、应用程序执行效率方面具有更多的优势。但是,采用C++语言也带来了编译/链接循环的负担,从而降低了软件开发效率。

你可以使用解释性语言如Tcl来开发应用程序原型,然后再转换为C++程序。或者搜索示例代码(VTK目录或者其他用户)然后将其转换为最终的实现语言。

VTK代码的语言转换比较直接。各个语言中都采用相同的类名和方法名;不同的只是实现细节和GUI接口。例如:

C++语言:

[cpp] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. anActor->GetProperty()->SetColor(red,green, blue)  

Tcl语言则为:

[plain] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. [anActorGetProperty] Set Color $red $green $blue  

Java语言为:

[java] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. anActor.GetProperty().SetColor(red,green, blue);  

Python为:

[python] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. anActor->GetProperty().SetColor(red,green, blue);  

由于指针操作问题,一些C++应用程序不能转换为其他三种语言,这也是语言转换时的一个主要限制。包装语言可以方便的获取或者设置对象的值,但是不能直接获取一个指针来快速遍历、检查或者修改大的数据结构。如果你的应用程序需要类似的操作,那你可以直接采用C++语言实现,或者利用C++扩展VTK生成你需要的类,然后使用你喜欢的解释性语言来使用新的类。


【第3章 翻译完毕】
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

VTK User’s Guide -11th edition 第03章-VTK系统概述(3) 的相关文章

  • STM32L431使用TencentOS tiny操作系统连接腾讯物联网开发平台

    去年腾讯为了宣传自己针对物联网的开源操作系统TencentOS tiny xff0c 举办了一场试用活动 xff0c 当时幸运获得一块 板子实物就这样 xff0c 没啥好介绍的 xff0c 都是基础的外设 xff0c 如今闲来无事 xff0
  • [总线技术]汽车ECU网络传输-诊断协议测试-基于Canoe软件CAPL脚本编写

    一 xff0e 汽车电子电控结构 先介绍一下汽车电子电控的结构 xff0c 汽车并不像电脑一样 xff0c 只有一个CPU xff0c 而是分为多个 CPU 独立工作 xff0c 就是由很多很多个控制器组成的 xff0c 比如 xff1a
  • [STM32F1]关于STM32F103芯片按钮机制串口发送程序

    就是目前遇到一个项目 xff0c 是监视各个按钮状态并将各个按钮的状态发送至上位机 xff0c 上位机进行整体程序逻辑动作 一般情况下串口发送可以直接一直发送给上位机 xff0c 通过解析不同数据位0和1的状态可以知道具体哪个按钮按下 xf
  • [uCOS/RTOS]freertos——创建任务(一)

    FreeRTOS操作系统学习 前言 FreeRTOS操作系统的学习正式开始 一 了解FreeRTOS FreeRTOS共有32个优先级 xff08 0 31 xff09 使用时0和31不使用 优先级规则 xff1a 数字越大优先级越高 任务
  • 基于FreeRTOS的UART空闲中断框架设计

    设计背景 xff1a 针对大部分国产低端MCU ARM CortexM0 来说 xff0c 并没有空闲中断 xff0c 此时就需要一个定时器Timer配合来完成此任务 对于UART接受不定长数据 xff0c 空闲中断还是非常实用的 xff0
  • 2、可迭代对象与迭代器

    1 Iterable 可迭代对象 概念 xff1a python中能够使用for循环遍历的都是可迭代对象 1 常见的可迭代对象 1 1 序列如 xff1a list str tuple range 1 2 非序列 xff1a dict se
  • 帮你分清嵌入式与单片机

    从事计算机和或电子行业相关领域工作的朋友 xff0c 一般都听说过单片机和嵌入式 但是要问单片机和嵌入式两者之间有什么联系 xff0c 大多数人都不能很好的解释清楚 想要弄清楚嵌入式和单片机有什么联系 xff0c 首先就要弄明白什么是嵌入式
  • [MM32生态]Python,让嵌入式应用开发更便捷、更高效、更专注

    前言 前面分享了基于PikaScript如何在MM32平台上部署Python开发环境的帖子 xff0c 实现了Python基础开发环境的部署 xff0c 可以通过串口终端软件在线编写Python xff0c 然后直接运行得到结果 通过Pyt
  • [STM32]STM32移植freemodbus实现modbusTCP

    上次说到采用STM32F1移植了FreeModbus协议栈进行开发实现ModBus RTU协议来进行一些线圈寄存器的控制 xff08 继电器开关 xff09 和一些保持寄存器的读写 xff08 参数配置灯 xff09 xff0c 这次说一下
  • FR8012HAQ利用ADC实现检测电池电压检测的解决方案

    今天要跟大家分享的是FR8012HAQ利用ADC实现检测电池电压检测的解决方案 FR8012HAQ是富芮坤的一款通用蓝牙芯片 特性介绍如下图 xff1a 我们再来看FR8012HAQ的PMU xff0c 它强大的地方还在于内置了充电模块 F
  • [单片机芯片]CH32V307驱动单总线温湿度传感器DHT22

    手头有一个DHT22温湿度传感器和CH32V307开发板 xff0c 可玩性极强 DHT22是已校准的数字温湿度传感器 xff0c 用于检测环境温湿度 xff0c 采用DHT22 AM2302 xff0c 标准单总线接口 拥有比常见的DHT
  • RT_Thread好用吗? RT_Thread成国内最成熟开源RTOS?

    RT Thread 是一款主要由中国开源社区主导开发的开源实时操作系统 许可证GPLv2 实时线程操作系统不仅仅是一个单一的实时操作系统内核 xff0c 它也是一个完整的应用系统 xff0c 包含了实时 嵌入式系统相关的各个组件 xff1a
  • [技术讨论]知识科普のARM和STM32之间的纠葛

    一 ARM和STM32的关系 ARM和STM32是两个不同的概念 xff0c ARM是一家英国公司 xff0c 专注于设计和许可处理器架构 xff0c 而STM32是ST公司基于ARM Cortex M内核的一系列微控制器产品 ARM Co
  • 嵌入式经历了哪些发展阶段?这些嵌入式法则你都了解吗?

    为增进大家对嵌入式的认识 xff0c 本文将对嵌入式发展阶段以及嵌入式中的一些法则予以介绍 嵌入式已经是现在的主流系统以及开发手段之一 xff0c 嵌入式工程师更是占据了一席之地 为增进大家对嵌入式的认识 xff0c 本文将对嵌入式发展阶段
  • 【技术分享】GD32硬件I2C调试中的问题与解决过程-续

    使用GD32303C EVAL开发板和MPL3115A2模块测量气压或高度数据 xff0c 两者间使用硬件I2C进行通讯 上次调试发现官方例程 xff08 单一I2C读写功能 xff09 可以正常读写MPL芯片的寄存器 xff0c 而我建立
  • [技术问答]HC32F460 是否有 RTC?在电池供电方案中该如何使用?

    背景 RTC xff0c 学名实时时钟芯片 xff0c 它是日常生活中应用较为广泛 xff0c 不管是消费类还是工业类的电子产品基本都要求带有时钟 日历或闹钟功能 xff0c 它为人们提供精确的实时时间 或者为电子系统提供精确的时间基准 实
  • 2021年本四小厂面试总结

    菜鸡小厂工程师 xff0c 还是徘徊在一万上下 xff0c 希望今年能拿到20k以上 2021 9 4更新 五月 汇丰 xff1a 1 kotlin 的 apply let 有什么区别 返回的是什么参数或者句子 kotlin作用域函数 ru
  • 关于STL的vector与OpenCV的Mat初始化问题记录

    问题情形 xff1a 需要记录不同的两个Opencv的Mat矩阵 xff0c 由于数量是动态确定的 且很可能 gt 4个 xff0c 所以想通过构建cv Mat的容器来保存结果 同时 xff0c 每个Mat必须初始化为0矩阵且分配内存 错误
  • reStructuredText 、Sphinx 资料汇总

    reStructuredText 用 reStructuredText 写作 xff1a 快速入门指南 reStructuredText rst 快速入门语法说明 reStructuredText rst 语法规则快速入门 在线 reStr
  • 300个韩国网站欣赏

    300个韩国网站欣赏 http www homepg co kr http www yoondesign com http www rodingallery org http www toyota co kr HYUNDAI http ww

随机推荐

  • 使用WinRAR来创建分卷压缩包

    因为科研需求 xff0c 需要将数据备份到百度云盘 xff0c 但很多数据量很大 xff0c 单个文件超过了20G xff0c 因此 xff0c 没有办法直接上传到百度云盘上去 xff0c 如下图 为了解决这个问题 xff0c 考虑到经常玩
  • 写论文时优雅的在word中添加程序代码

    一 工具 打开这个网页PlanetB 如下图 xff1a 二 步骤 1 将你需要插入在word中的代码完整的复制到该网站提示的文本框内 xff0c 选择你的代码类型 xff0c 如C C 43 43 HTML等 xff0c 并点击提交 如下
  • stm32中库函数和hal库的区别

    今天在b站看一个关于嵌入式的视频 xff0c 讲述使用stm32cube软件的 了解这些的小伙伴们应该知道STM32CubeMX 是意法半导体推出的图形化配置工具 xff0c 通过傻瓜化的操作便能实现相关配置 xff0c 最终能够生成C语言
  • python+selenium自动化能打开火狐浏览器但是打不开网址

    python 43 selenium 执行自动化脚本时能打开火狐浏览器而打不开网址时 提示 xff1a Unsupported Marionette protocol version 2 required 3 是由版本不兼容导致的 我安装的
  • 使用docker运行gitlab服务

    之前 xff0c 在服务器上直接安装配置过gitlab xff0c 感觉需要配置安装的东西还是挺多的 xff1a git xff0c redis xff0c postgresql xff0c nginx等 这么多服务一起 xff0c 备份和
  • Kubernetes运维之使用Prometheus全方位监控K8S (概念篇)

    目录 xff1a Prometheus架构 K8S监控指标及实现思路 在K8S平台部署Prometheus 基于K8S服务发现的配置解析 在K8S平台部署Grafana 监控K8S集群中Pod Node 资源对象 使用Grafana可视化展
  • Grafana 告警配置、告警通道及告警内容的安装和配置

    本文主要介绍grafana的告警是如何配置的 xff0c 以及在触发告警时通过邮件和企业微信消息将告警通知给用户 xff0c 最后介绍了如何在告警内容中添加告警时刻的panel图片 告警配置 grafana的告警触发以panel为基础 xf
  • 【面经】momenta 二面

    二面好像主要针对C 43 43 研发来的 所以就基本上问的算法题 面试官小哥哥超nice的 xff0c 整个过程都很耐心 xff0c 最后还细心的讲解了全部的题目 这也太好了8 map的底层实现 xff0c 红黑树 C 43 43 11的了
  • stm32串口通信

    stm32串口通信 基于寄存器与基于固件库编写的差异 使用固件库 xff0c 目前比较多的例程是使用固件库编写的 固件库编写方式 xff0c 特点是简单易于理解 xff0c 资料多 新手适合用这种方式入门 使用寄存器 xff0c 想要深入理
  • markdown和reStructuredText语法简单比较

    PyCharm默认的代码注释就是reStructuredText风格的 加之之前学习 实验设计 这门课的时候 用过readthedocs 43 sphinx写过文档 其默认的格式就是reStructuredText风格的 所以比较好奇 当时
  • python之BeautifulSoup之二 带属性值的抓取(find_all('tag', attrs={'class':'value'})

    系统 xff1a Windows python 2 7 11 利用BeautifulSoup库抓取页面的一些标签TAG值 再抓取一些特定属性的值 示例标签 xff1a lt cc gt lt div id 61 34 post conten
  • 关于租用香港服务器疑问解答

    关于租用香港服务器许多用户还有很多疑问 xff0c 那么下面由专门做海外服务器租用 托管的RAKsmart机房进行疑问解答 香港服务器器租用疑问如下 xff1a 问题一 xff1a 租用香港服务器违法吗 xff1f 租用香港服务器不违法 x
  • 三维重建方法--激光or视觉

    导读 xff1a 激光雷达则是无人驾驶和扫地机器人等领域的核心一环 那么为什么出现多种方案呢 xff1f 它们到底有什么差异 xff1f 看似很酷炫的技术 xff0c 实际上并没有外界想得那么高大上 Realsense之所以能够识别物体的深
  • 虚拟机中ubuntu的中文输入法安装

    1 安装中文语言包 xff0c 在终端里面运行 这个不是很熟悉 xff0c 下面还有些命令 xff0c 但是我只运行了这几个 xff0c 后面就可以顺利安装了 原理不太清楚 sudo apt get install scim sudo ap
  • 1、Ubuntu下安装软件报错

    今天在ubuntu下安装任何软件都提示以下错误 xff1a ideallic 64 ubuntu sudo apt get install git sudo password for ideallic Reading package lis
  • 查看安装的ROS版本号

    1 先在终端输入roscore 2 打开新终端 xff0c 再输入 xff0c rosparam list 3 再输入rosparam get rosdistro就能得到版本
  • [fake_turtlebo.launch] is neither a launch file in package [rbx1_bringup] nor is [rbx1_bringup] ...

    1 问题描述如下 xff1a 2 执行如下命令 export grep ROS 发现ROS PACKAGE PATH不包含本包的路径 3 执行以下命令 cd catkin ws catkin make source devel setup
  • 用C++实现一个简单的PID控制器

    用C 43 43 实现一个简单的PID控制器 先上代码 xff0c 原理后面再补充 span class token macro property span class token directive keyword include spa
  • VTK User’s Guide -11th edition 第01章-欢迎学习VTK

    本节对应原书中的第3页至第7页 欢迎开启VTK之旅 VTK用户指南 VTK是一个开源的 面向对象的计算机图形 可视化和图像处理的软件系统 虽然VTK比较庞大 复杂 xff0c 但是当你了解了它基本的面向对象的设计和实现的方法以后 xff0c
  • VTK User’s Guide -11th edition 第03章-VTK系统概述(3)

    本节对应原书中的第29页至第39页 3 2创建VTK应用程序 本章内容包括利用Tcl xff0c C 43 43 xff0c Java和Python四种语言开发VTK应用程序的基本知识 阅读完引言后 xff0c 你应该了解用你擅长的语言进行