Hashtable Interface to MIDP RecordStore

The javax.microedition.rms package provides the Record Management System (RMS) implementation. It is a kind of DBMS, but its API doesnot resemble JDBC or any of other J2SE APIs. The primary concept of RMS is the RecordStore. The RecordStore element is the Record, and Record's essence is a byte array.

I have created a special adaptor to the RMS. It doesnot cover all the RMS capabilities but allows us to use RMS as a backend for a Map-like object structure. There is no java.util.Map interface in MIDP, so our "RecordMap" adapter uses java.util.Hashtable as a pattern. Even more, it extends java.util.Hashtable. It is a pure interface inheritance, all the methods are overridden in our RecordMap.

Our RecordMap is configurable in that it can be parameterized with different implementations of our own EntryMapper interface to provide the concrete functionality of the data mapping between Hashtable key-value pairs and RecordStore byte arrays.

package j2mefancier;

public interface EntryMapper {

byte[] bytes(Object key, Object value);

Object key(byte[] bytes);

Object value(byte[] bytes);

}

Then, here is a couple of small utility classes used by our RecordMap:

package j2mefancier;

import java.util.*;
import javax.microedition.rms.*;

public class EnumAdapter implements Enumeration {

private RecordEnumeration re;
private EntryMapper mapper;
private boolean isKey;

public EnumAdapter(RecordStore rs, EntryMapper mapper, boolean isKey) throws RecordStoreException {
this.re = rs.enumerateRecords(null, null, false);
this.mapper = mapper;
this.isKey = isKey;
}

public boolean hasMoreElements() {
return re.hasNextElement();
}

public Object nextElement() {
try {
byte[] bytes = re.nextRecord();
return isKey ? mapper.key(bytes) : mapper.value(bytes);
} catch (RecordStoreException e) {
return null;
}
}

}
package j2mefancier;

import javax.microedition.rms.*;

public class Filter implements RecordFilter {

private Object obj;
private EntryMapper mapper;
private boolean isKey;

public Filter(Object obj, EntryMapper mapper, boolean isKey) {
if (obj == null) throw new NullPointerException();
this.obj = obj;
this.mapper = mapper;
this.isKey = isKey;
}

public boolean matches(byte[] candidate) {
return obj.equals(isKey ? mapper.key(candidate) : mapper.value(candidate));
}

}

Now, look at the implementation of the EntryMapper interface I use for own purposes. Note that it allows only String keys and values, so the best use case of this implementation is for RMS backend of Properties-like data. Again, there is no java.util.Properties in MIDP, otherwise I'd prefer to use Properties API instead of Hashtable one. Other use cases require more intelligent entry mappers.

package j2mefancier;

import java.io.*;

public class EntryMapperImpl implements EntryMapper {

public byte[] bytes(Object key, Object value) {
if (! (key instanceof String) || ! (value instanceof String))
throw new IllegalArgumentException();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
try {
dos.writeUTF(key.toString());
dos.writeUTF(value.toString());
dos.close();
} catch (IOException e) {
e.printStackTrace();
}
return baos.toByteArray();
}

public Object key(byte[] bytes) {
DataInputStream dis = new DataInputStream(new ByteArrayInputStream(bytes));
try {
return dis.readUTF();
} catch (IOException e) {
return null;
}
}

public Object value(byte[] bytes) {
DataInputStream dis = new DataInputStream(new ByteArrayInputStream(bytes));
try {
dis.readUTF();
return dis.readUTF();
} catch (IOException e) {
return null;
}
}

}

And here is the heart of the thing: the RecordMap class. I don't insist on its implementation optimality etc., the main purpose is to demonstrate the idea. Probably you can develop more efficient implementations for some use cases and also add more clever exception handling. The usual Hashtable toString() functionality is omitted to keep the code more compact.

package j2mefancier;

import java.util.*;
import javax.microedition.rms.*;

public class RecordMap extends Hashtable {

private RecordStore rs;
private EntryMapper mapper;

public RecordMap(RecordStore rs, EntryMapper mapper) {
this.rs = rs;
this.mapper = mapper;
}

public void clear() {
try {
RecordEnumeration re = rs.enumerateRecords(null, null, false);
while (re.hasNextElement()) rs.deleteRecord(re.nextRecordId());
} catch (RecordStoreException e) {
throw wrapped(e);
}
}

public boolean contains(Object value) {
try {
RecordEnumeration re = rs.enumerateRecords(new Filter(value, mapper, false), null, false);
return re.hasNextElement();
} catch (RecordStoreException e) {
throw wrapped(e);
}
}

public boolean containsKey(Object key) {
return get(key) != null;
}

public Enumeration elements() {
try {
return new EnumAdapter(rs, mapper, false);
} catch (RecordStoreException e) {
throw wrapped(e);
}
}

public Object get(Object key) {
try {
RecordEnumeration re = rs.enumerateRecords(new Filter(key, mapper, true), null, false);
if (re.hasNextElement()) return mapper.value(re.nextRecord());
return null;
} catch (RecordStoreException e) {
throw wrapped(e);
}
}

public boolean isEmpty() {
return size() == 0;
}

public Enumeration keys() {
try {
return new EnumAdapter(rs, mapper, true);
} catch (RecordStoreException e) {
throw wrapped(e);
}
}

public Object put(Object key, Object value) {
if (value == null) throw new NullPointerException();
try {
Object old = remove(key);
byte[] bytes = mapper.bytes(key, value);
rs.addRecord(bytes, 0, bytes.length);
return old;
} catch (RecordStoreException e) {
throw wrapped(e);
}
}

public Object remove(Object key) {
try {
RecordEnumeration re = rs.enumerateRecords(new Filter(key, mapper, true), null, false);
if (re.hasNextElement()) {
Object old = mapper.value(re.nextRecord());
rs.deleteRecord(re.previousRecordId());
return old;
}
return null;
} catch (RecordStoreException e) {
throw wrapped(e);
}
}

public int size() {
try {
return rs.getNumRecords();
} catch (RecordStoreException e) {
throw wrapped(e);
}
}

public String toString() {
try {
return "RecordMap-" + rs.getName();
} catch (RecordStoreException e) {
throw wrapped(e);
}
}

private RuntimeException wrapped(RecordStoreException e) {
return new RuntimeException(e.getMessage());
}

}
 
内容概要:本文围绕六自由度机械臂的人工神经网络(ANN)设计展开,重点研究了正向与逆向运动学求解、正向动力学控制以及基于拉格朗日-欧拉法推导逆向动力学方程,并通过Matlab代码实现相关算法。文章结合理论推导与仿真实践,利用人工神经网络对复杂的非线性关系进行建模与逼近,提升机械臂运动控制的精度与效率。同时涵盖了路径规划中的RRT算法与B样条优化方法,形成从运动学到动力学再到轨迹优化的完整技术链条。; 适合人群:具备一定机器人学、自动控制理论基础,熟悉Matlab编程,从事智能控制、机器人控制、运动学六自由度机械臂ANN人工神经网络设计:正向逆向运动学求解、正向动力学控制、拉格朗日-欧拉法推导逆向动力学方程(Matlab代码实现)建模等相关方向的研究生、科研人员及工程技术人员。; 使用场景及目标:①掌握机械臂正/逆运动学的数学建模与ANN求解方法;②理解拉格朗日-欧拉法在动力学建模中的应用;③实现基于神经网络的动力学补偿与高精度轨迹跟踪控制;④结合RRT与B样条完成平滑路径规划与优化。; 阅读建议:建议读者结合Matlab代码动手实践,先从运动学建模入手,逐步深入动力学分析与神经网络训练,注重理论推导与仿真实验的结合,以充分理解机械臂控制系统的设计流程与优化策略。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值