diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 4dadd63..9d19f81 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -17,8 +17,8 @@ + android:versionCode="140626" + android:versionName="14.06.26" > Sets the camera for this surface view.

+ * + * @param camera The camera to set. + */ public void setCamera(Camera camera){ this.camera = camera; if(this.camera != null){ - Logger.log_d(TAG, CLASS_NAME + ".setCamera() :: Setting camera."); + Logger.log_d(TAG, CLASS_NAME + ".setCamera(): Setting camera."); imgMonitor = CameraImageMonitor.getInstance(); requestLayout(); - Logger.log_d(TAG, CLASS_NAME + ".setCamera() :: Camera set."); + Logger.log_d(TAG, CLASS_NAME + ".setCamera(): Camera set."); } } + @Override public void surfaceCreated(SurfaceHolder holder){ // The Surface has been created, now tell the camera where to draw the preview. - Logger.log_d(TAG, CLASS_NAME + ".surfaceCreated() :: Creating surface view."); + Logger.log_d(TAG, CLASS_NAME + ".surfaceCreated(): Creating surface view."); try { if(camera != null) camera.setPreviewDisplay(holder); } catch (IOException e) { - Logger.log_e(TAG, CLASS_NAME + ".surfaceCreated() :: Error creating camera: " + e.getMessage()); + Logger.log_e(TAG, CLASS_NAME + ".surfaceCreated(): Error creating camera: " + e.getMessage()); } } + @Override public void surfaceDestroyed(SurfaceHolder holder){ if(camera != null) camera.stopPreview(); } + @Override public void surfaceChanged(SurfaceHolder tmpHolder, int format, int w, int h){ - int result; - int rotation; - int degrees = 0; - Camera.Parameters camParams; + int result; + int rotation; + int degrees = 0; + Size optimal; + CameraInfo info; + List sizes; + Parameters camParams; - Logger.log_d(TAG, CLASS_NAME + ".surfaceChanged() :: Method started."); + Logger.log_d(TAG, CLASS_NAME + ".surfaceChanged(): Method started."); if(this.holder.getSurface() == null || camera == null){ - Logger.log_d(TAG, CLASS_NAME + ".surfaceChanged() :: Holder and/or camera are null."); + Logger.log_d(TAG, CLASS_NAME + ".surfaceChanged(): Holder and/or camera are null."); return; } try{ camera.stopPreview(); }catch (Exception e){ } + Logger.log_d(TAG, CLASS_NAME + ".surfaceChanged(): Request layout."); requestLayout(); + Logger.log_d(TAG, CLASS_NAME + ".surfaceChanged(): Get parameters."); camParams = camera.getParameters(); - camParams.getSupportedPreviewSizes(); - List sizes = camParams.getSupportedPreviewSizes(); - - for(Size size: sizes){ - Logger.log_d(TAG, CLASS_NAME + ".surfaceChanged() :: Supported preview size (" + size.width + ", " + size.height + ")"); - } - - /*Size optimal = getOptimalPreviewSize(sizes, w, h); - Logger.log_d(TAG, CLASS_NAME + ".surfaceChanged() :: Preview size set at (" + optimal.width + ", " + optimal.height + ")"); - camParams.setPreviewSize(optimal.width, optimal.height);*/ - camParams.setPreviewSize(352, 288); - camera.setParameters(camParams); - /*previewWidth = optimal.width; - previewHeight = optimal.height;*/ - previewWidth = 352; - previewHeight = 288; + sizes = camParams.getSupportedPreviewSizes(); - android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo(); - android.hardware.Camera.getCameraInfo(0, info); + for(Size size: sizes){ + Logger.log_d(TAG, CLASS_NAME + ".surfaceChanged(): Supported preview size (" + size.width + ", " + size.height + ")"); + } + + optimal = getOptimalPreviewSize(sizes, camera.new Size(OPTIMAL_WIDTH, OPTIMAL_HEIGHT)); + Logger.log_d(TAG, CLASS_NAME + ".surfaceChanged(): Preview size set at (" + optimal.width + ", " + optimal.height + ")"); + camParams.setPreviewSize(optimal.width, optimal.height); + camera.setParameters(camParams); + previewWidth = optimal.width; + previewHeight = optimal.height; + + info = new CameraInfo(); + Camera.getCameraInfo(0, info); rotation = parentActivity.getWindowManager().getDefaultDisplay().getRotation(); switch (rotation) { - case Surface.ROTATION_0: degrees = 0; break; - case Surface.ROTATION_90: degrees = 90; break; - case Surface.ROTATION_180: degrees = 180; break; - case Surface.ROTATION_270: degrees = 270; break; + default: + case Surface.ROTATION_0: + degrees = 0; + break; + + case Surface.ROTATION_90: + degrees = 90; + break; + + case Surface.ROTATION_180: + degrees = 180; + break; + + case Surface.ROTATION_270: + degrees = 270; + break; } - if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { + if (info.facing == CameraInfo.CAMERA_FACING_FRONT) { result = (info.orientation + degrees) % 360; result = (360 - result) % 360; // compensate the mirror } else { // back-facing @@ -146,7 +170,7 @@ public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback camera.setPreviewDisplay(this.holder); camera.startPreview(); }catch (Exception e){ - Logger.log_e(TAG, CLASS_NAME + ".surfaceChanged() :: Error starting camera preview: " + e.getMessage()); + Logger.log_e(TAG, CLASS_NAME + ".surfaceChanged(): Error starting camera preview: " + e.getMessage()); } } @@ -154,51 +178,47 @@ public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback public void onPreviewFrame(byte[] data, Camera camera){ if(imgMonitor.hasChanged()) imgMonitor.setImageParameters(previewWidth, previewHeight); - Logger.log_d(TAG, CLASS_NAME + ".onPreviewFrame() :: Preview received"); - Logger.log_d(TAG, CLASS_NAME + ".onPreviewFrame() :: Frame has" + (imgMonitor.hasChanged() ? "" : " not") + " been consumed."); imgMonitor.setImageData(data); } + /** + *

If camera is not null then disable the camera preview.

+ */ public void removePreviewCallback(){ if(camera != null) camera.setPreviewCallback(null); } - private Size getOptimalPreviewSize(List sizes, int w, int h) { - final double ASPECT_TOLERANCE = 0.1; - double targetRatio = (double) w / h; + /** + *

Tries to obtain the preview size that better matches the target size pixel dimensions.

+ * + * @param sizes An initialized list of supported preview sizes. + * @param target The ideal preview size. + * @return The size from the list of sizes that better matches the target. Null if sizes is null or empty. + */ + private Size getOptimalPreviewSize(List sizes, final Size target) { + final int TARGET_HEIGHT = target.height; + Size optimalSize = null; + double minDiff = Double.MAX_VALUE; - Logger.log_d(TAG, CLASS_NAME + ".getOptimalPreviewSize() :: Method started."); - if (sizes == null) return null; - - Size optimalSize = null; - double minDiff = Double.MAX_VALUE; - - int targetHeight = h; - - // Try to find an size match aspect ratio and size - for (Size size : sizes) { - double ratio = (double) size.width / size.height; - if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue; - if (Math.abs(size.height - targetHeight) < minDiff) { - optimalSize = size; - minDiff = Math.abs(size.height - targetHeight); - } - } + if (sizes == null || sizes.size() == 0) return null; // Cannot find the one match the aspect ratio, ignore the requirement if (optimalSize == null) { + Logger.log_d(TAG, CLASS_NAME + ".getOptimalPreviewSize(): Ignoring aspect ratio."); minDiff = Double.MAX_VALUE; for (Size size : sizes) { - if (Math.abs(size.height - targetHeight) < minDiff) { + if (Math.abs(size.height - TARGET_HEIGHT) < minDiff) { optimalSize = size; - minDiff = Math.abs(size.height - targetHeight); + minDiff = Math.abs(size.height - TARGET_HEIGHT); + Logger.log_d(TAG, CLASS_NAME + ".getOptimalPreviewSize(): Size = (" + Integer.toString(size.width) + ", " + Integer.toString(size.width) + ")"); + Logger.log_d(TAG, CLASS_NAME + ".getOptimalPreviewSize(): minDiff = " + Double.toString(minDiff)); } } } - Logger.log_d(TAG, CLASS_NAME + ".getOptimalPreviewSize() :: Method ended."); - Logger.log_d(TAG, CLASS_NAME + ".getOptimalPreviewSize() :: Optimal size is: (" + Integer.toString(optimalSize.width) + - ", " + Integer.toString(optimalSize.height) + ")"); + + Logger.log_d(TAG, CLASS_NAME + ".getOptimalPreviewSize(): Optimal size found is (" + Integer.toString(optimalSize.width) + ", " + Integer.toString(optimalSize.height) + ")"); + return optimalSize; } } diff --git a/src/ve/ucv/ciens/ccg/nxtcam/network/NxtBTCommThread.java b/src/ve/ucv/ciens/ccg/nxtcam/network/NxtBTCommThread.java index f8f4dff..281f96e 100644 --- a/src/ve/ucv/ciens/ccg/nxtcam/network/NxtBTCommThread.java +++ b/src/ve/ucv/ciens/ccg/nxtcam/network/NxtBTCommThread.java @@ -73,11 +73,16 @@ public class NxtBTCommThread extends Thread{ msg[0] |= (event.getMotor() == motor_t.MOTOR_C) ? MotorMasks.MOTOR_C : 0; // Set the direction bit. if(event.getPower() > 0) msg[0] |= MotorMasks.DIRECTION; - // Set the recenter bits. + // Set the recenter bit. msg[0] |= (event.getMotor() == motor_t.RECENTER) ? MotorMasks.RECENTER : 0; if((msg[0] & MotorMasks.RECENTER) > 0) Logger.log_i(TAG, CLASS_NAME + ".run(): Recenter received."); + // Set the rotate bit. + msg[0] |= (event.getMotor() == motor_t.ROTATE_90) ? MotorMasks.ROTATE_90 : 0; + if((msg[0] & MotorMasks.ROTATE_90) > 0) + Logger.log_i(TAG, CLASS_NAME + ".run(): Rotate 90 received."); + // Set the power byte. msg[1] = (byte)Math.abs(event.getPower()); diff --git a/src/ve/ucv/ciens/ccg/nxtcam/network/protocols/MotorMasks.java b/src/ve/ucv/ciens/ccg/nxtcam/network/protocols/MotorMasks.java index 1c0bd61..af6db72 100644 --- a/src/ve/ucv/ciens/ccg/nxtcam/network/protocols/MotorMasks.java +++ b/src/ve/ucv/ciens/ccg/nxtcam/network/protocols/MotorMasks.java @@ -18,7 +18,8 @@ package ve.ucv.ciens.ccg.nxtcam.network.protocols; /** *

Bit masks used to code/decode the control instructions sent by NxtAR-cam to * NxtAR-bot.

- *

Expansions 1-3 are currently unused.

+ * + *

Expansions 2-3 are currently unused.

*/ public abstract class MotorMasks { public static final byte MOTOR_A = (byte)0x01; @@ -26,7 +27,7 @@ public abstract class MotorMasks { public static final byte MOTOR_C = (byte)0x04; public static final byte DIRECTION = (byte)0x08; public static final byte RECENTER = (byte)0x10; - public static final byte EXPANSION_1 = (byte)0x20; - public static final byte EXPANSION_2 = (byte)0x20; - public static final byte EXPANSION_3 = (byte)0x20; + public static final byte ROTATE_90 = (byte)0x20; + public static final byte EXPANSION_2 = (byte)0x40; + public static final byte EXPANSION_3 = (byte)0x80; }