用Pollinate可视化开发页面流(JPF)

1 Pollinate下载、安装
1.1 工具下载
1.1.1 Servlet容器—Tomcat5.5.8
  Eclipse的安装插件后默认的Servlet容器就是Tomcat,所以这里选择了Tomcat5.5.8作为Servlet容器,后面的例子也以Tomcat5.5.8为例来讲解,如果你使用其他的Servlet容器或者Tomcat的其他版本,请按照您的环境进行相应的调整。
  Tomcat的下载站点: http://jakarta.apache.org/site/binindex.cgi

1.1.2 Eclipse3.1M5a
  Pollinate要求使用Eclipse3.1M5a版本,这是截止到本文写作时Eclipse的最新稳定版本,下载地址: http://download.eclipse.org/eclipse/downloads/drops/S-3.1M5a-200502191500/index.php

1.1.3 JDK5.0
  Pollinate中使用了Sun JDK中的APT(Annotation Processing Tool)工具来处理代码中的批注,所以要求采用JDK5.0 update1或者以上版本。JDK5.0系列的下载地址是: http://java.sun.com/j2se/1.5.0/download.jsp,请选择合适的版本下载。

1.1.4 Pollinate
  Pollinate插件的最新版本是1.0.0.M3,可以到 http://www.eclipse.org/downloads/download.php?file=/technology/pollinate/org.eclipse.pollinate-1.0.0.M3.zip去下载安装包。

1.1.5 Web Tools和其他插件
  Pollinate插件是基于Web Tools 1.0 M3和其他插件开发的,所以还需要下载Web Tools和其他插件的安装,在Web Tools1.0M3的下载中提供这些插件的打包下载,所以大家可以到 http://www.eclipse.org/downloads/download.php?file=/webtools/downloads/drops/S-1.0M3-200502260707/wtp-prereqs-sdk-1.0M3.zip直接下载就可以了。

1.2 软件安装
  软件安装的工作比较简单,不过还是需要注意步骤,否则安装很可能失败:
  1. 安装JDK
  2. 解压缩Tomcat,并且让Tomcat可以正常运行
  3. 解压缩Eclipse
  4. 解压缩Web Tools和其他插件,并且把他们安装到Eclipse上
  5. 解压缩Pollinate,把他安装到Eclipse上
2 使用Pollinate开发页面流
  作者将用一个例子来演示如何使用Pollinate开发页面流,这个例子非常简单,就是一个通常的用户注册页面,用户需要提供三个字段:用户名、密码和常用E_Mail,服务器端获取用户输入的内容,并且用另一个JSP页面显示出来。
  作者的演示环境和相关的说明都是基于Windows 2000平台的,如果您使用其它的操作系统平台,可能需要相应的变更才能够完成整个开发过程。

2.1 启动Eclipse
  需要注意一下,因为Pollinate需要用到JDK5.0中的Annotation Processing Tool,所以启动的时候需要增加些参数,下面是正确的步骤:
  1、 进入Eclipse安装目录
  2、 创建一个新的starteclipse.cmd文件,文件的内容如下:
   请修改JAVA_HOME的值
   修改为指向您安装JDK50 update 1或者以上版本的文件目录
  set JAVA_HOME=d:jdk50
  eclipse.exe -vm % JAVA_HOME %jreinjavaw -vmargs -Xbootclasspath/a:% JAVA_HOME %ib ools.jar
3、 现在通过双击starteclipse.cmd启动Eclipse

2.2 创建页面流开发工程
2.2.1 设置工作目录
  打开Eclipse,首先进入工作目录设置界面,请输入或者选择您期望的工作目录,作者的工作目录设置为c:pollinate。

 

2.2.2 创建服务器
  安装Web Tools插件后,我们可以直接在Eclipse中启动、停止Web容器实例,也可以将开发的Web应用直接发布到指定的Web容器中,下面是创建服务器实例的步骤:
  1. 打开菜单FileàNewàOther,选择ServerServer向导,单击”Next”

  2. 选择创建Tomcat5.5类型的服务器实例,单击”Next”

  3. 输入Tomcat的相关配置信息,主要是服务器的安装目录:

  4. 单击”Finish”完成服务器的创建

2.2.3 创建支持页面流的工程
  1. 打开菜单FileàNewàOther,选择PollinateBeehive Project,创建一个工程,单击”Next”

  2. 输入Web工程的名字和发布到Tomcat后的上下文路径名,单击”Next”:

  3. 选择创建页面流简单环境,单击”Finish”:

2.2.4 设置工程的Java编译器
  Eclipse默认的Java编译是1.4版本的,Pollinate编译需要用Java的5.0编译器,所以需要修改:
  1. 在pollinate工程图标上单击右键打开上下文菜单,选择”Properties”

  2. 修改工程的Java Compile属性如下,单击确定:

2.2.5 将创建的Web工程发布到服务器
  1. 打开windowàShow ViewàOther,选择显示ServerServers视图,单击”OK”:

  2. 在视图中选择创建的服务器实例,单击右键打开上下文菜单,选择add and remove project …

  3. 发布工程或者取消某些工程发布

  • 左边的列表显示目前还没有发布的工程
  • 右边的列表显示已经发布的工程
  • 选中左边列表中的工程,单击“Add >”,表示将这个工程发布到服务器上
  • 选择右边列表中的工程,单击“< Remove”表示将发布到服务器上的工程移出服务器

  我们这里选择发布pollinate工程,最后单击”Finish” 结束发布。

2.3 开发步骤
  现在我们打开windowàopen PerspectiveàOther,选择打开J2EE透视图,展开Project浏览器中的Dynamic Web Projects节点,可以看到我们创建的pollinate工程。
2.3.1 用向导创建PageFlow
  1. 选择pollinate项目下WebContent文件夹,单击右键打开上下文菜单
  2. 选择FileàNewàOther,选择PollinatePage Flow Wizard,创建一个页面流,单击”Next”

  3. 修改PageFlow所在的目录名为samples,这时WebContent目录下会增加一个samples目录,目录下面是Controller.java和index.jsp两个文件
现在打开pollinate工程中的WebContentsamples目录下的Controller.java文件,Eclipse将使用Page Flow的专用编辑器打开它,我们单击该编辑器的Flow标签,可以进入可视化的界面,这就是我们真正想要的东西。

2.3.2 增加一个Action
  我们在Page Flow编辑器左边的工具框单击 图标,然后在右边的PageFlow显示区单击鼠标,将给我们的页面流增加一个名为newAction的映射。

2.3.3 增加一个JSP页面
  增加JSP页面的步骤和2.3.1增加一个Action的步骤基本相同,只是左边工具框中选择的图标便成了

2.3.4 增加页面导航
  现在我们将newAction和newPage.jsp联系起来,将newPage.jsp设置为newAction的一个Forward。
  选择左边工具框中的 图标,然后在newAction的图标上单击,然后移动鼠标到newPage.jsp的图标,它们之间将出现一条黑线,在newPage.jsp的图标上单击鼠标,它们之间将出现一条蓝色的连线,还有一个箭头:

2.3.5 准备接受用户输入的JSP
  在index.jsp的图标上右键打开上下文菜单,单击“open”打开index.jsp文件的编辑器,将index.jsp文件的内容修改为如下:
 <%@ page language="java" contentType="text/html;charset=UTF-8"%>
 <%@ taglib uri="http://beehive.apache.org/netui/tags-databinding-1.0" prefix="netui-data"%>
 <%@ taglib uri="http://beehive.apache.org/netui/tags-html-1.0" prefix="netui"%>
 <%@ taglib uri="http://beehive.apache.org/netui/tags-template-1.0" prefix="netui-template"%>
 <netui:html>
  <head>
  <title>Web Application Page</title>
  <netui:base/>
  </head>
 <netui:body>
<p>
 <netui:form action="newAction ">
  Name:<netui:textBox dataSource="actionForm.name"/><br/>
  Age:<netui:textBox dataSource="actionForm.age"/><br/>
  <netui:button type="submit">Submit</netui:button>
  </netui:form>

</p>
 </netui:body>
</netui:html>

2.3.6 实现数据处理
  在newAction的图标上右键打开上下文菜单,单击“open”回到Page Flow编辑器的source视图:
  1. 在Controller.jpf中增加一个内部类UForm,用于处理表单
static class UForm extends FormData
 {
  // 用户输入三个字段,FormBean提供三个属性和他们一一对应
  // 并且分别提供getter,setter方法
  private String name;
  private String password;
  private String email;

  public void setName(String name)
   {
    this.name = name;
   }

  public String getName()
   {
   return this.name;
   }

  public void setPassword(String pwd)
   {
   this.password = pwd;
   }

  public String getPassword()
   {
   return this.password;
   }

  public void setEmail(String mail)
   {
   this.email = mail;
   }

  public String getEmail()
   {
   return this.email;
   }
}

2. 修改newAction的签名,使他支持表单接收
 public Forward newAction(UForm form) {
 //在控制台打印用户输入
 System.out.println(“name=” + form.getName());
 System.out.println(“email=” + form.getEmail());
 //将用户输入表单传递给下一个显示页
  this.getRequest().setAttribute(“form”,form);
  return new Forward("success");
  }
  现在我们如果切换回Page Flow的Flow标签页,看到的效果和2.3.3增加页面导航步骤完成后看到的图型会有些不一样—index.jsp和newAction的图标之间自动产生了连线(为了看得清楚,图中图标的位置经过调整)

  从上面的这个图中,我们可以很清楚的看到页面流中各成员之间的关系:

  • begin动作完成后,显示index.jsp文件的内容
  • index.jsp中的form被newAction处理
  • newAction处理完了显示newPage.jsp的内容

2.3.7 显示用户输入
修改后的newPage.jsp文件内容如下:
  <%@ page language="java" contentType="text/html;charset=UTF-8"%>
  <%@ taglib uri="http://beehive.apache.org/netui/tags-databinding-1.0" prefix="netui-data"%>
  <%@ taglib uri="http://beehive.apache.org/netui/tags-html-1.0" prefix="netui"%>
  <%@ taglib uri="http://beehive.apache.org/netui/tags-template-1.0" prefix="netui-template"%>
  <netui:html>
    <head>
    <title>Web Application Page</title>
  <netui:base/>
    </head>
  <netui:body>
<p>
  下面显示用户输入的内容:<br/>
  name:<netui:span value=""/>
  password:<netui:span value=""/>
  email:<netui:span value=""/>
  </p>
  </netui:body>
</netui:html>

3 Pollinate1.0的优缺点
  经过上面的操作过程,我们可以发现目前的Pollinate1.0版本已经实现了可视化开发的部分功能,比如:支持使用向导来创建页面流,支持可视化的显示页面流的构成组件和相互之间的关系,支持动作(Action)到JSP页面之间的导航设置;当然缺点也还有不少,比如JSP页面到动作(Action)之间的导航(也就是Form的action属性设置)还只能通过手工实现等等,相比于Workshop中页面流开发的可视化,Pollinate还任重而道远。

4 总结
  文章中详细的讲述了如何安装Pollinate插件以及其他支持插件的过程,讲叙了如何在Eclipse中配置服务器使Eclipse支持Web开发和Servlet容器管理的操作步骤,最后通过一个简单的例子演示了如何使用Pollinate开发页面流的过程。

 作者简介
 唯J族(www.vivianj.org)创始人,BEA 杭州User Group负责人,自由撰稿人,开源项目BuildFileDesigner(buildfiledesign.sourceforge.net)和V-Security(v-security.sourceforge.net)创始人。
#define INTERPOLATION_STEPS 70 // 插值点数 #define MOTION_DELAY_MS 100 // 每步延时(ms) #define MAX_FLOWERS 3 // 最大雌花数量 #define POLLINATION_STEPS 50 // 授粉动作插值点数 float current_x, current_y; // 实时坐标 float current_alpha; // 当前姿态角 // 定义状态枚举 enum { STATE_NORMAL_MOVE, STATE_WAIT_POLLINATE2, STATE_EXEC_POLLINATE } move_state = STATE_NORMAL_MOVE; void linear_move(float x_start, float y_start, float x_end, float y_end, float alpha) { static float saved_x, saved_y, saved_alpha; static int saved_step; static float pollinate_target_x, pollinate_target_y; static int pollinate_substep; float dx = (x_end - x_start)/INTERPOLATION_STEPS; float dy = (y_end - y_start)/INTERPOLATION_STEPS; for(int step=0; step<=INTERPOLATION_STEPS; ) { // 正常运动计算 current_x = x_start + step*dx; current_y = y_start + step*dy; current_alpha = alpha; // 状态机处理 switch(move_state) { case STATE_NORMAL_MOVE: // 发送中间点指令 if(step == 5 || step == 38 || step == 60) { Serial_SendString("b"); Delay_ms(11); // 合并延时 } // 检测授粉信号 if(need_pollinate) { saved_x = current_x; saved_y = current_y; saved_alpha = current_alpha; saved_step = step; move_state = STATE_WAIT_POLLINATE2; } step++; // 正常状态下递增步数 break; case STATE_WAIT_POLLINATE2: // 保持当前位置 current_x = saved_x; current_y = saved_y; current_alpha = saved_alpha; // 等待第二个信号 if(need_pollinate2) { float pollinate_dist = 0.08f; pollinate_target_x = saved_x + pollinate_dist * cosf(saved_alpha); pollinate_target_y = saved_y + pollinate_dist * sinf(saved_alpha); pollinate_substep = 0; move_state = STATE_EXEC_POLLINATE; } break; case STATE_EXEC_POLLINATE: // 执行授粉动作 if(pollinate_substep <= 50) { // 总步数=前进50+返回50 // 前进阶段 if(pollinate_substep <= 25) { float ratio = (float)pollinate_substep / 25; current_x = saved_x + (pollinate_target_x - saved_x) * ratio; current_y = saved_y + (pollinate_target_y - saved_y) * ratio; } // 返回阶段 else { float ratio = (float)(pollinate_substep - 25) / 25; current_x = pollinate_target_x + (saved_x - pollinate_target_x) * ratio; current_y = pollinate_target_y + (saved_y - pollinate_target_y) * ratio; } pollinate_substep++; current_alpha = saved_alpha; } // 完成授粉 else { need_pollinate = 0; need_pollinate2 = 0; move_state = STATE_NORMAL_MOVE; // 恢复原始路径 step = saved_step; // 继续从暂停点开始 current_x = saved_x; current_y = saved_y; // 立即执行一次正常运动 Kinematic_Analysis(current_x, current_y, current_alpha); pwm_out(90, (-90 + theta1), (-theta2), (-theta3)); Delay_ms(MOTION_DELAY_MS); step++; // 恢复后递增步数 } break; } // 运动控制 Kinematic_Analysis(current_x, current_y, current_alpha); pwm_out(90, (-90 + theta1), (-theta2), (-theta3)); if(stopflag) { move_state = STATE_NORMAL_MOVE; // 重置状态 break; } Delay_ms(MOTION_DELAY_MS); } move_state = STATE_NORMAL_MOVE; // 完成路径后重置状态 } 和void USART2_IRQHandler(void) { if (USART_GetITStatus(USART2, USART_IT_RXNE) == SET) { uint8_t received = USART_ReceiveData(USART2); // 遇到换行符开始处理 if(received == '\n') { rx_buffer[rx_index] = '\0'; if(rx_buffer[0] == 'D' && rx_buffer[1] == ':') { // 距离信息 uart2_rx_distance = atoi((char*)rx_buffer + 2); printf("Distance: %d\r\n", uart2_rx_distance); } else if(rx_buffer[0] == 'S') { // stopflag=1; need_pollinate = 1; // 仅在C区响应停车指令 if(current_zone == ZONE_C) { // stopflag=1; need_pollinate = 1; } else if(current_zone == ZONE_B) { // pollination_signal = 1; // 使用原B区标志 // stopflag=1; need_pollinate = 1; } else if(current_zone == ZONE_A) { need_pollinate = 1; // 简单标志位 // stopflag = 1; } } else if(rx_buffer[0] == 'Q') { // 仅在C区完成时响应 if(current_zone == ZONE_C) { c_wanchengflag=1; } } else if(rx_buffer[0] == 'w') { need_pollinate2 = 1; printf(" %d\r\n", need_pollinate2); // 调试:打印当前状态 // printf("Current state: %d\n", move_state); } // 底座调整指令 else if(rx_buffer[0] == 'L') { // 向左微调 move_base(1.0, &base_angle); // 自动延时 } else if(rx_buffer[0] == 'R') { // 向右微调 move_base(-1.0, &base_angle); // 自动延时 } rx_index = 0; // 重置缓冲区 } else if(rx_index < MAX_CMD_LEN-1) { rx_buffer[rx_index++] = received; } USART_ClearITPendingBit(USART2, USART_IT_RXNE); } } 和arduino代码 // 处理K210数据 if (Serial3.available()) { String k210_data = Serial3.readStringUntil('\n'); k210_data.trim(); int firstComma = k210_data.indexOf(','); int secondComma = k210_data.indexOf(',', firstComma+1); if (firstComma != -1 && secondComma != -1) { String classID = k210_data.substring(0, firstComma); float x = k210_data.substring(firstComma+1, secondComma).toFloat(); float y = k210_data.substring(secondComma+1).toFloat(); Serial.print("[K210] Class:"); Serial.print(classID); Serial.print(" X:"); Serial.print(x); Serial.print(" Y:"); Serial.println(y); // 雌花检测 if (classID == "4" || classID == "2") { // 检查Y坐标是否在屏幕中央区域 if (y >= CENTER_Y_MIN && y <= CENTER_Y_MAX) { // 计算X坐标偏差 int x_diff = CENTER_X - (int)x; // 处理调整逻辑 if (isAdjusting) { // 检查是否超时 if (millis() - adjustStartTime > ADJUST_TIMEOUT) { isAdjusting = false; // Serial2.print("w\n"); // 超时也尝试授粉 Serial.println("Adjust timeout, force pollinate"); } // 满足条件才发送调整指令(1秒间隔) else if (abs(x_diff) > X_THRESHOLD) { if (millis() - lastAdjustTime > ADJUST_INTERVAL) { if (x_diff > 0) { Serial2.print("L\n"); Serial.println("Send L command"); } else { Serial2.print("R\n"); Serial.println("Send R command"); } lastAdjustTime = millis(); // 更新发送时间 } } // 调整完成 else { Serial2.print("w\n"); isAdjusting = false; Serial.println("Adjust complete, send w"); } } // 首次检测到需要调整 else if (abs(x_diff) > X_THRESHOLD) { isAdjusting = true; adjustStartTime = millis(); // 立即发送第一次调整指令 if (x_diff > 0) { Serial2.print("L\n"); Serial.println("Start adjust: L"); } else { Serial2.print("R\n"); Serial.println("Start adjust: R"); } lastAdjustTime = millis(); // 记录首次发送时间 } // 已在中心位置 else { Serial2.print("w\n"); Serial.println("Center position, send w"); } // 每3秒发送一次S信号(保持不变) if (millis() - lastSendTime >= 30000) { Serial2.print("S\n"); lastSendTime = millis(); Serial.println("Send S command"); } } } 现在调整好之后stm32可以受到need_pollinate2 = 1;但是无法授粉动作
最新发布
06-23
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值