float feedbackValue = ...; //这里获取到被控对象的反馈值float targetValue = ...; //这里获取到目标值
时间: 2024-09-08 17:02:37 浏览: 52
在这个上下文中,`feedbackValue` 和 `targetValue` 是两个浮点数变量,通常用于控制系统中的反馈控制过程。`feedbackValue` 表示当前系统的状态或输出,而 `targetValue` 则代表期望达到的目标状态或设定值。在很多自动化控制算法中,比如PID控制器,会将这两个值进行比较和计算,以调整系统的输入以便让系统接近或达到目标。
例如,在PID控制中,可能会有如下的计算公式:
```csharp
errorValue = targetValue - feedbackValue;
proportionalTerm = errorValue * proportionalGain;
integralTerm = integralTerm + (errorValue * integralGain) * timeStep;
derivativeTerm = (errorValue - previousError) / timeStep;
controlOutput = proportionalTerm + integralTerm + derivativeTerm;
previousError = errorValue;
// 这里的控制Output会被用来改变被控对象的行为
```
其中,`proportionalTerm`, `integralTerm`, 和 `derivativeTerm` 分别对应于比例、积分和微分三种控制策略,它们结合起来帮助系统减小误差并趋向于目标值。
相关问题
下段代码 可以拖动,但缩放和旋转时会闪退,请改正 public boolean onTouchEvent(MotionEvent event) { switch (event.getAction() & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: // 手指压下屏幕 mode = MODE.DRAG; // 查找被点击的图片 int index = event.getActionIndex(); float x = event.getX(index); float y = event.getY(index); CustomBitmap clickedBitmap = findClickedBitmap(x, y); if (clickedBitmap != null) { // 切换操作对象 _bitmaps.remove(clickedBitmap); _bitmaps.add(clickedBitmap); // 记录ImageView当前的移动位置 currentMatrix.set(clickedBitmap.matrix); clickedBitmap.matrix.set(currentMatrix); clickedBitmap.startPoint.set(x, y); _curCustomBitmap = clickedBitmap; } postInvalidate(); break; case MotionEvent.ACTION_POINTER_DOWN: // 当屏幕上还有触点(手指),再有一个手指压下屏幕 mode = MODE.ZOOM; // 记录位图的旋转角度和缩放倍数 _curCustomBitmap.oldRotation = rotation(event); _curCustomBitmap.startDis = distance(event); if (_curCustomBitmap.startDis > 10f) { // 获取缩放中心点的坐标 float x1 = event.getX(0); float y1 = event.getY(0); float x2 = event.getX(1); float y2 = event.getY(1); _curCustomBitmap.midPoint.set((x1 + x2) / 2, (y1 + y2) / 2); // 记录ImageView当前的缩放倍数 currentMatrix.set(_curCustomBitmap.matrix); } break; case MotionEvent.ACTION_MOVE: // 手指在屏幕移动,该事件会不断地触发 if (mode == MODE.DRAG) { // 移动图片 float dx = event.getX() - _curCustomBitmap.startPoint.x; float dy = event.getY() - _curCustomBitmap.startPoint.y; _curCustomBitmap.matrix.set(currentMatrix); _curCustomBitmap.matrix.postTranslate(dx, dy); } else if (mode == MODE.ZOOM) { // 缩放和旋转图片 float endDis = distance(event); float rotation = rotation(event) - _curCustomBitmap.oldRotation; if (endDis > 10f) { float scale = endDis / _curCustomBitmap.startDis; _curCustomBitmap.matrix.set(currentMatrix); _curCustomBitmap.matrix.postScale(scale, scale, _curCustomBitmap.midPoint.x, _curCustomBitmap.midPoint.y); _curCustomBitmap.matrix.postRotate(rotation, _curCustomBitmap.midPoint.x, _curCustomBitmap.midPoint.y); } } break; case MotionEvent.ACTION_POINTER_UP: // 有手指离开屏幕,但屏幕还有触点(手指) mode = MODE.NONE; break; } invalidate(); return true;
可能是因为在缩放和旋转时,没有判断当前操作的图片是否为null,导致空指针异常。可以在缩放和旋转的代码之前添加判断,如果当前操作的图片为空,就直接返回。修改后的代码如下:
```
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
// 手指压下屏幕
mode = MODE.DRAG;
// 查找被点击的图片
int index = event.getActionIndex();
float x = event.getX(index);
float y = event.getY(index);
CustomBitmap clickedBitmap = findClickedBitmap(x, y);
if (clickedBitmap != null) {
// 切换操作对象
_bitmaps.remove(clickedBitmap);
_bitmaps.add(clickedBitmap);
// 记录ImageView当前的移动位置
currentMatrix.set(clickedBitmap.matrix);
clickedBitmap.matrix.set(currentMatrix);
clickedBitmap.startPoint.set(x, y);
_curCustomBitmap = clickedBitmap;
}
postInvalidate();
break;
case MotionEvent.ACTION_POINTER_DOWN:
// 当屏幕上还有触点(手指),再有一个手指压下屏幕
mode = MODE.ZOOM;
// 记录位图的旋转角度和缩放倍数
if (_curCustomBitmap == null) {
return true;
}
_curCustomBitmap.oldRotation = rotation(event);
_curCustomBitmap.startDis = distance(event);
if (_curCustomBitmap.startDis > 10f) {
// 获取缩放中心点的坐标
float x1 = event.getX(0);
float y1 = event.getY(0);
float x2 = event.getX(1);
float y2 = event.getY(1);
_curCustomBitmap.midPoint.set((x1 + x2) / 2, (y1 + y2) / 2);
// 记录ImageView当前的缩放倍数
currentMatrix.set(_curCustomBitmap.matrix);
}
break;
case MotionEvent.ACTION_MOVE:
// 手指在屏幕移动,该事件会不断地触发
if (mode == MODE.DRAG) {
// 移动图片
if (_curCustomBitmap == null) {
return true;
}
float dx = event.getX() - _curCustomBitmap.startPoint.x;
float dy = event.getY() - _curCustomBitmap.startPoint.y;
_curCustomBitmap.matrix.set(currentMatrix);
_curCustomBitmap.matrix.postTranslate(dx, dy);
} else if (mode == MODE.ZOOM) {
// 缩放和旋转图片
if (_curCustomBitmap == null) {
return true;
}
float endDis = distance(event);
float rotation = rotation(event) - _curCustomBitmap.oldRotation;
if (endDis > 10f) {
float scale = endDis / _curCustomBitmap.startDis;
_curCustomBitmap.matrix.set(currentMatrix);
_curCustomBitmap.matrix.postScale(scale, scale, _curCustomBitmap.midPoint.x, _curCustomBitmap.midPoint.y);
_curCustomBitmap.matrix.postRotate(rotation, _curCustomBitmap.midPoint.x, _curCustomBitmap.midPoint.y);
}
}
break;
case MotionEvent.ACTION_POINTER_UP:
// 有手指离开屏幕,但屏幕还有触点(手指)
mode = MODE.NONE;
break;
}
invalidate();
return true;
}
```
float binVal =hist.at<float>(h)
### 访问 OpenCV 中直方图元素
在 OpenCV 中,`hist.at<float>(i)` 是一种用于访问 `Mat` 对象中特定位置元素的方式。对于存储直方图数据的矩阵而言,这允许精确读取或修改指定索引处的浮点数值。
当处理单通道灰度图像时,创建并填充好直方图之后可以通过如下方法来获取其内部的具体值:
```cpp
// 假设 hist 已经是一个已经计算好的直方图 Mat 对象
float value = hist.at<float>(i); // i 表示要查询的位置下标
```
这段代码会返回位于第 `i` 个桶(bin)内的频率计数[^1]。
需要注意的是,在实际应用之前应当确认直方图确实是以 `CV_32F` 或者其他支持浮点运算的数据类型构建而成;否则尝试通过 `.at<float>()` 进行访问可能会引发异常错误。通常情况下,使用默认参数设置的话,OpenCV 的直方图函数将会自动选择合适的数据格式[^4]。
此外,如果遇到多维直方图,则需要提供更多的坐标分量给 `.at<T>` 函数以便定位到具体的单元格。例如在一个二维颜色空间上的分布情况分析里,就需要传递两个维度的信息作为输入参数[^3]。
阅读全文
相关推荐
















