栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

利用树莓派订阅智能小车坐标数据并利用scoket实时传输到云端mysql

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

利用树莓派订阅智能小车坐标数据并利用scoket实时传输到云端mysql

关于树莓派我用的镜像是塔克创新里提供的镜像

云端用的是阿里云,里面先安装mysql,然后做了一些配置(这个我配置了很久,大概是参照这两个网址:1130 - Host XXX is not allowed to connect to this MySQL server 错误提示的解决办法。_荆棘云海的博客-CSDN博客和

(转)重置密码遇到ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using passwor:yes)问题_微仔的黄金小屋-CSDN博客

然后下载navicat就可以可视化mysql了

接着准备服务端的代码,这是我老师提供的,应该可以进行收发的功能,我并没有做太多改动,懂java的可以改改,我是先利用vscode的扩展插件ssh-remote连接至云端

//package tcpipchapter3;

import java.awt.List;
import java.io.*;
import java.net.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.ArrayList;
import java.sql.*;

public class App {
 
 //设置端口号/
 public static int portNo=3333;
     //Mysql连接的初始设置
 public static Connection con = null;
 public static     String driver = "com.mysql.jdbc.Driver";
 public static     String url = "jdbc:mysql://localhost:3306/mysql数据库名字";
 public static     String user = "云端帐号";
 public static     String password = "云端账号密码";  

 public static String readSQLItems(){
     String cycle_line = "";
     //-----------------------------------------------------------------------------------------
    //把数据库内容读出来,发送回客户端
    try {
        //加载驱动程序
        Class.forName(driver);
       //getConnection()方法,连接MySQL数据库!!
        con = DriverManager.getConnection(url,user,password);
        if(!con.isClosed())
            System.out.println("Succeeded connecting to the Database!");        
        //创建statement类对象,用来执行SQL语句!!
        Statement statement = con.createStatement();
  
        //要执行的SQL语句
        String sql = "select * from car_cycle_data"; //"select * from car_cycle_data order by id DESC limit 1"; //"select *   from car_cycle_data where id=(select max(id) from car_cycle_data)"; //查找最后一行记录,也就是最新插入的一行记录        
        //3.ResultSet类,用来存放获取的结果集!!
        ResultSet rs = statement.executeQuery(sql);
        ResultSetmetaData md = rs.getmetaData();//获取键名
        int columnCount = md.getColumnCount();//获取行的数量
       while(rs.next())  { 
            for (int i = 1; i <= columnCount; i++) {
                cycle_line = cycle_line+" "+ rs.getString(i);//获取键名及值
            }
            cycle_line = cycle_line+"n";
       }       
        con.close();
    } 
    catch(SQLException e) {
        e.printStackTrace();  
        }
        catch (Exception e) {
            e.printStackTrace();
        }
            finally{
                System.out.println("数据库表读取完成!!");
            }
    return cycle_line;
 }

 public static void main(String[] args) throws IOException {

   //-----------------------------------------------------------------------------------------
  //初始化serverSocket类
  ServerSocket s=new ServerSocket(portNo,10,InetAddress.getByName("云端内网网址"));
  System.out.println("The Server is starting...");
  //建立socket连接(阻塞,直到有客户端连接)
  Socket socket=s.accept();

  //接收数据
  try{
    //构造输入流缓存
    BufferedReader bufReader=new BufferedReader(new InputStreamReader(socket.getInputStream()));
    PrintWriter out=new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true);
    String time=new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(new Date());
    while(true){
        //按行读取输入内容
        String strLine=bufReader.readLine();
        //如果收到byebye则退出循环
        if(strLine.equals("query all")){
            out.println("Results readed from cloud database: "+ readSQLItems());
            break;
        }
    System.out.println("In the Server reveived: "+strLine);

    //-----------------------------------------------------------------------------------------
    //把strline内容写入数据库
    try {
        //加载驱动程序
        Class.forName(driver);
       //getConnection()方法,连接MySQL数据库!!
        con = DriverManager.getConnection(url,user,password);
        if(!con.isClosed())
            System.out.println("Succeeded connecting to the Database!");        
        //要执行的SQL语句
       // String sql = "INSERT INTO car_cycle_data(id,encoder_right,encoder_left,acceleration_x,acceleration_y,acceleration_z,gyroscope_x,gyroscope_y,gyroscope_z,magnetometer_x,magnetometer_y,magnetometer_z,electromagnetic_right,electromagnetic_center,electromagnetic_left,off_center,steering_gear_control,motor_control_left,motor_control_right,P_value,I_value,D_value) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
//上面这句话变量有22个,问号也有22个,而且变量名字要跟你数据库表里的要一致,否则传不到数据
       String sql = "INSERT INTO car_cycle_data(x,y) VALUES(?,?)";
       PreparedStatement pstm = con.prepareStatement(sql);
        String[] field = strLine.split(","); //按空格符分割接收到的字符串
        for (int i=0;i 

然后准备的是客户端的代码,我用的是python写的,因为我用的是塔克创新的镜像,所以先用vscode连接树莓派,然后创建功能包(这里参考b站古月居的方式),完成这些工作之后启动xtark_driver.launch节点,这个节点启动之后在打开功能包(就是下面这个代码)就可以订阅/odom的话题消息并且实时传输/odom数据,想要其他数据类型也可以照着改一下,这里我说一下编写的思路,我首先是在ros_ws里的xtark_driver.cpp里查看了该话题的消息类型,然后查看到是nav_msgs::Odometry,因为要用到的是pythom,所以又到里面去翻了翻有关nav_msgs库的代码文件,找到了Odometry类。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import rospy
from  nav_msgs.msg import Odometry
from socket import *
import time
from typing import Text

HOST='你云端的ip地址'
PORT=3333
ADDR=(HOST, PORT)

tcpCliSock=socket(AF_INET, SOCK_STREAM)
tcpCliSock.connect(ADDR)

def poseCallback(msg):
    l1 = str(msg.pose.pose.position.x)
    l2 = str(msg.pose.pose.position.y)
    l3 = l1+","+l2+"n"
    l3=str.encode(l3)
    rospy.loginfo(l3)
    tcpCliSock.send(l3)
    time.sleep(0.5) # 休眠1秒

def pose_subscriber():
    # ROS节点初始化
    rospy.init_node('pose_subscriber', anonymous=True)
    
    # 创建一个Subscriber,订阅名为/turtle1/pose的topic,注册回调函数poseCallback

    rospy.Subscriber("/odom", Odometry, poseCallback)
    time.sleep(0.5)
    # 循环等待回调函数
    rospy.spin()
#tcpCliSock.close()

if __name__ == '__main__':
    pose_subscriber()

最后给一下结果, 因为我只用了stm32和树莓派,没连上电机,因此odom数据都是0

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/340914.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号