使用 udp 在 java 和 simulink 之间传输双倍
transfer doubles between java and simulink using udp
我需要在 Java 程序和 Simulink 模型之间传输十进制值,为此我使用 UDP 套接字,它们在 java 端没有问题。
在 Simulink 中,我可以使用 'Stream Output' 块发送值,但是从 java 接收时出现问题!
'Stream input' 块没有收到任何东西。
我使用的是标准设备 UDP 协议,具有正确的本地 UDP 端口,地址是“本地主机”。
请告诉我如何使用 udp 在 simulink 中正确接收双精度数据,或者甚至使用其他方法,传输数据是什么问题。
提前致谢。
这里有一些代码:
localSocket = new DatagramSocket(9010);
...
public static void localSend(String msg,int PORT) throws Exception{
DatagramPacket sendPacket = null,encPacket=null;
try {
sendPacket = new DatagramPacket(msg.getBytes(), msg.getBytes().length, InetAddress.getLocalHost(), PORT);
} catch (Exception e) {
System.out.printf("Error!");
}
localSocket.send(sendPacket);
}
在主要方法中:
localSend(myMessage, 9005);
'Input Stream'块的'Board setup'是Simulink如下:
这是我如何从 Simulink ins Java(方法)接收数据:
public static String localReceive() throws Exception{
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
int count=0;
try {
localSocket.receive(receivePacket);
return new String(receivePacket.getData(),receivePacket.getOffset(),receivePacket.getLength());
} catch (SocketTimeoutException socketTimeoutException) {
return defaultValue;
}
}
和 Simulink 中 "Output Stream" 块的设置:
我做了个把戏。
'Packet Input' Simulink 块,和 'ASCII Decode',
我调整这2个block的参数如下:
并且在java这边,我'reformat'双倍的,用这个方法:
public static String reformat(String str){
double d = 0;
DecimalFormat df=null;
try {
d = Double.parseDouble(str);
} catch (NumberFormatException numberFormatException) {
return "0.00000";
}
if(d>=0){
String[] sp=str.split("\.");
if(sp[0].length()==0)
df= new DecimalFormat("0.00000");
if(sp[0].length()==1)
df= new DecimalFormat("0.00000");
if(sp[0].length()==2)
df= new DecimalFormat("00.0000");
if(sp[0].length()==3)
df= new DecimalFormat("000.000");
if(sp[0].length()==4)
df= new DecimalFormat("0000.00");
if(sp[0].length()==5)
df= new DecimalFormat("00000.0");
}
else{
String[] sp=str.split("\.");
if(sp[0].length()==1)
df= new DecimalFormat("0.0000");
if(sp[0].length()==2)
df= new DecimalFormat("0.0000");
if(sp[0].length()==3)
df= new DecimalFormat("00.000");
if(sp[0].length()==4)
df= new DecimalFormat("000.00");
if(sp[0].length()==5)
df= new DecimalFormat("0000.0");
if(sp[0].length()==6)
df= new DecimalFormat("000000");
}
try {
return df.format(d);
} catch (Exception e) {
return "0.00000";
}
}
简而言之:数据包输入块每次接收7个ASCII,并且在java中我重新格式化double以组合7个字符(包括点和减号)。
希望这对某人有所帮助。
更新:
some self explanatory extra code:
//somewhere before:
//Global variables
String defaultValue="0",ip="xxx.xx.xx.xx";
DatagramSocket remoteSocket,localSocket;
byte[] receiveArray,receiveKey,receiveSig,sendSig;
int remoteSendPort=xxx,localSendport=xxx,
remoteReceivePort=xxx,localReceivePort=xxx;
String feedback,control_val,ReceivedTimeStamp;
InetAddress IPAddress;
...
//receive message from the other java program in pc2
public void remoteMsgSend(byte[] msg,InetAddress IPAddress, int PORT) {
try {
DatagramPacket sendPacket = null;
try {
sendPacket = new DatagramPacket(msg, msg.length, IPAddress, PORT);
} catch (Exception e) {
System.out.printf("Error! check ports");
}
remoteSocket.send(sendPacket);
} catch (IOException ex) {
System.out.println("IOException! remote send");
}
}
//receive message from the other java program in pc2
public String remoteMsgReceive() {
DatagramPacket receivePacket = new DatagramPacket(receiveArray, receiveArray.length);
byte[] r1;
int count=0,len,offset;
try {
remoteSocket.receive(receivePacket);
r1=receivePacket.getData();
len=receivePacket.getLength();
offset=receivePacket.getOffset();
r1=Arrays.copyOfRange(r1, offset, len);
remoteOk=true;
return new String(r1);
} catch (Exception ex) {
// System.out.println("remote receive time out: " +ex.getMessage());
remoteOk=false;
return defaultValue;
}
}
//send data to matlab on this pc
public void localSend(String msg,int PORT) {
DatagramPacket sendPacket = null;
try {
sendPacket = new DatagramPacket(msg.getBytes(), msg.getBytes().length, InetAddress.getLocalHost(), PORT);
} catch (Exception e) {
System.out.printf("Error! check ports");
}
try {
localSocket.send(sendPacket);
} catch (IOException ex) {
System.out.println("localsend error");
}
}
//receive data from Matlab on this pc
public String localReceive() {
DatagramPacket receivePacket = new DatagramPacket(receiveArray, receiveArray.length);
String rec;
try {
localSocket.receive(receivePacket);
rec=new String(receivePacket.getData(),receivePacket.getOffset(),receivePacket.getLength());
localOk=true;
return rec;
} catch (Exception ex) {
// System.out.println("local receive time out " +ex.getMessage());
localOk=false;
return defaultValue;
}
}
另一种方案,在Simulink中输入流。
只需为来自 java.
的每条消息添加一个终止符“\n”
我需要在 Java 程序和 Simulink 模型之间传输十进制值,为此我使用 UDP 套接字,它们在 java 端没有问题。 在 Simulink 中,我可以使用 'Stream Output' 块发送值,但是从 java 接收时出现问题! 'Stream input' 块没有收到任何东西。 我使用的是标准设备 UDP 协议,具有正确的本地 UDP 端口,地址是“本地主机”。 请告诉我如何使用 udp 在 simulink 中正确接收双精度数据,或者甚至使用其他方法,传输数据是什么问题。 提前致谢。 这里有一些代码:
localSocket = new DatagramSocket(9010);
...
public static void localSend(String msg,int PORT) throws Exception{
DatagramPacket sendPacket = null,encPacket=null;
try {
sendPacket = new DatagramPacket(msg.getBytes(), msg.getBytes().length, InetAddress.getLocalHost(), PORT);
} catch (Exception e) {
System.out.printf("Error!");
}
localSocket.send(sendPacket);
}
在主要方法中:
localSend(myMessage, 9005);
'Input Stream'块的'Board setup'是Simulink如下:
这是我如何从 Simulink ins Java(方法)接收数据:
public static String localReceive() throws Exception{
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
int count=0;
try {
localSocket.receive(receivePacket);
return new String(receivePacket.getData(),receivePacket.getOffset(),receivePacket.getLength());
} catch (SocketTimeoutException socketTimeoutException) {
return defaultValue;
}
}
和 Simulink 中 "Output Stream" 块的设置:
我做了个把戏。
'Packet Input' Simulink 块,和 'ASCII Decode',
我调整这2个block的参数如下:
并且在java这边,我'reformat'双倍的,用这个方法:
public static String reformat(String str){
double d = 0;
DecimalFormat df=null;
try {
d = Double.parseDouble(str);
} catch (NumberFormatException numberFormatException) {
return "0.00000";
}
if(d>=0){
String[] sp=str.split("\.");
if(sp[0].length()==0)
df= new DecimalFormat("0.00000");
if(sp[0].length()==1)
df= new DecimalFormat("0.00000");
if(sp[0].length()==2)
df= new DecimalFormat("00.0000");
if(sp[0].length()==3)
df= new DecimalFormat("000.000");
if(sp[0].length()==4)
df= new DecimalFormat("0000.00");
if(sp[0].length()==5)
df= new DecimalFormat("00000.0");
}
else{
String[] sp=str.split("\.");
if(sp[0].length()==1)
df= new DecimalFormat("0.0000");
if(sp[0].length()==2)
df= new DecimalFormat("0.0000");
if(sp[0].length()==3)
df= new DecimalFormat("00.000");
if(sp[0].length()==4)
df= new DecimalFormat("000.00");
if(sp[0].length()==5)
df= new DecimalFormat("0000.0");
if(sp[0].length()==6)
df= new DecimalFormat("000000");
}
try {
return df.format(d);
} catch (Exception e) {
return "0.00000";
}
}
简而言之:数据包输入块每次接收7个ASCII,并且在java中我重新格式化double以组合7个字符(包括点和减号)。
希望这对某人有所帮助。
更新:
some self explanatory extra code:
//somewhere before:
//Global variables
String defaultValue="0",ip="xxx.xx.xx.xx";
DatagramSocket remoteSocket,localSocket;
byte[] receiveArray,receiveKey,receiveSig,sendSig;
int remoteSendPort=xxx,localSendport=xxx,
remoteReceivePort=xxx,localReceivePort=xxx;
String feedback,control_val,ReceivedTimeStamp;
InetAddress IPAddress;
...
//receive message from the other java program in pc2
public void remoteMsgSend(byte[] msg,InetAddress IPAddress, int PORT) {
try {
DatagramPacket sendPacket = null;
try {
sendPacket = new DatagramPacket(msg, msg.length, IPAddress, PORT);
} catch (Exception e) {
System.out.printf("Error! check ports");
}
remoteSocket.send(sendPacket);
} catch (IOException ex) {
System.out.println("IOException! remote send");
}
}
//receive message from the other java program in pc2
public String remoteMsgReceive() {
DatagramPacket receivePacket = new DatagramPacket(receiveArray, receiveArray.length);
byte[] r1;
int count=0,len,offset;
try {
remoteSocket.receive(receivePacket);
r1=receivePacket.getData();
len=receivePacket.getLength();
offset=receivePacket.getOffset();
r1=Arrays.copyOfRange(r1, offset, len);
remoteOk=true;
return new String(r1);
} catch (Exception ex) {
// System.out.println("remote receive time out: " +ex.getMessage());
remoteOk=false;
return defaultValue;
}
}
//send data to matlab on this pc
public void localSend(String msg,int PORT) {
DatagramPacket sendPacket = null;
try {
sendPacket = new DatagramPacket(msg.getBytes(), msg.getBytes().length, InetAddress.getLocalHost(), PORT);
} catch (Exception e) {
System.out.printf("Error! check ports");
}
try {
localSocket.send(sendPacket);
} catch (IOException ex) {
System.out.println("localsend error");
}
}
//receive data from Matlab on this pc
public String localReceive() {
DatagramPacket receivePacket = new DatagramPacket(receiveArray, receiveArray.length);
String rec;
try {
localSocket.receive(receivePacket);
rec=new String(receivePacket.getData(),receivePacket.getOffset(),receivePacket.getLength());
localOk=true;
return rec;
} catch (Exception ex) {
// System.out.println("local receive time out " +ex.getMessage());
localOk=false;
return defaultValue;
}
}
另一种方案,在Simulink中输入流。 只需为来自 java.
的每条消息添加一个终止符“\n”