ROS键盘控制机器人

目录

前言&&过程分析

第一步

第二步

第三步

第四步

PC端(上位机)代码

远程机器人(下位机)代码


前言&&过程分析

当我们需要使用键盘控制机器人的时候,通常,分为几步。

第一步

首先要会读取键盘事件,并判断哪个键盘按下去了,返回按下的按键键值。

这里有检测键盘按下事件的帖子:C++监听键盘事件(读取键盘输入)_qqliuzhitong的博客-CSDN博客

第二步

然后,我们的上位机(nanopi k2)根据按下去的按键的键值,发布一个指令消息,来广播这个键值。

第三步

接着,我们用下位机,另一台nanopi k2或者是一个arduino板子,来订阅这个指令消息。

第四步

最后,下位机(nanopi k2或者arduino板子)判断指令,根据指令进行相应,控制电机或者舵机,这样就完成了一个从上位机按下键盘按键到最终机器人做出反应的一个流程。

PC端(上位机)代码

#include <ros/ros.h>
#include <std_msgs/UInt16.h>
#include <termio.h>
#include <stdio.h>

#define KEYCODE_W 0x77
#define KEYCODE_A 0x61
#define KEYCODE_S 0x73
#define KEYCODE_D 0x64
#define KEYCODE_I 0x69
#define KEYCODE_J 0x6A
#define KEYCODE_K 0x6B
#define KEYCODE_L 0x6C
#define KEYCODE_SPACE 0x20

#define KEYCODE_A_CAP 0x41
#define KEYCODE_D_CAP 0x44
#define KEYCODE_S_CAP 0x53
#define KEYCODE_W_CAP 0x57


int key_command=0x00;

void scanKeyboard()
{
	struct termios new_settings;
	struct termios stored_settings;
    //设置终端参数
	tcgetattr(0,&stored_settings);
	new_settings = stored_settings;
	new_settings.c_lflag &= (~ICANON);
	new_settings.c_cc[VTIME] = 0;
	tcgetattr(0,&stored_settings);
	new_settings.c_cc[VMIN] = 1;
	tcsetattr(0,TCSANOW,&new_settings);
	key_command = getchar();
	tcsetattr(0,TCSANOW,&stored_settings);
}

int main(int argc, char  *argv[])
{
    setlocale(LC_ALL,"");
    ros::init(argc,argv,"keyboard_control");
    ros::NodeHandle nh;

    ros::Publisher key_publisher = nh.advertise<std_msgs::UInt16>("key_command",10);
    std_msgs::UInt16 key_c;//w:1  a:2  s:3  d:4  i:5  j:6  k:7  l:8

	while(1){
		scanKeyboard();
		switch(key_command)
		{
			case KEYCODE_W:
				key_c.data=1;
				key_publisher.publish(key_c);
				break;
			case KEYCODE_A:
				key_c.data=2;
				key_publisher.publish(key_c);
				break;
			case KEYCODE_S:
				key_c.data=3;
				key_publisher.publish(key_c);
				break;
			case KEYCODE_D:
				key_c.data=4;
				key_publisher.publish(key_c);
				break;

			case KEYCODE_I:
				key_c.data=5;
				key_publisher.publish(key_c);
				break;
			case KEYCODE_J:
				key_c.data=6;
				key_publisher.publish(key_c);
				break;
			case KEYCODE_K:
				key_c.data=7;
				key_publisher.publish(key_c);
				break;
			case KEYCODE_L:
				key_c.data=8;
				key_publisher.publish(key_c);
				break;

			default:
				key_c.data=1;
				key_publisher.publish(key_c);
				break;
		}

	}
}

cmakelists.txt文件:

add_executable(keyboard src/keyboard.cpp)
target_link_libraries(keyboard
 ${catkin_LIBRARIES}
)

远程机器人(下位机)代码

#include <ros/ros.h>



#include <serial/serial.h>



#include <iostream>



#include <std_msgs/UInt16.h>

 





//创建一个serial类



serial::Serial sp;







uint8_t hello1[12]={0xfa,0x10,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0xf1};

uint8_t hello2[12]={0xfa,0x10,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0xf2};

uint8_t hello3[12]={0xfa,0x10,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0xf3};

uint8_t hello4[12]={0xfa,0x10,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0xf4};

uint8_t hello5[12]={0xfa,0x10,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0xf5};

uint8_t hello6[12]={0xfa,0x10,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0xf6};

uint8_t hello7[12]={0xfa,0x10,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0xf7};

uint8_t hello8[12]={0xfa,0x10,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0xf8};



uint8_t hello9[12]={0xfa,0x10,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0xf9};

uint8_t hello10[12]={0xfa,0x10,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0xfa};

uint8_t hello11[12]={0xfa,0x10,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0xfb};



void command_Callback(const std_msgs::UInt16& key_c)

{

       ros::Rate loop_rate(1);

	

	switch(key_c.data)

	{	

		case 1:

		sp.write(hello1, 12);

		break;

		case 2:

		sp.write(hello2, 12);

		break;

		case 3:

		sp.write(hello3, 12);

		break;

		case 4:

		sp.write(hello4, 12);

		break;

		case 5:

		sp.write(hello5, 12);

		break;

		case 6:

		sp.write(hello6, 12);

		break;

		case 7:

		sp.write(hello7, 12);

		break;

		case 8:

		sp.write(hello8, 12);

		break;

		case 9:

		sp.write(hello9, 12);

		loop_rate.sleep();

		sp.write(hello10, 12);

		loop_rate.sleep();

		sp.write(hello11, 12);

		loop_rate.sleep();

		

		break;

		default:;

	}

//    ROS_INFO("hello");

}





int main(int argc, char** argv)



{



    ros::init(argc, argv, "serial_port");



    ros::NodeHandle n;

    //创建serial timeout

    serial::Timeout to = serial::Timeout::simpleTimeout(100);



    //设置要打开的串口名称



    sp.setPort("/dev/ttyUSB0");



    //设置串口通信的波特率



    sp.setBaudrate(9600);



    //串口设置timeout



    sp.setTimeout(to);



    try



    {



        //打开串口



        sp.open();



    }



    catch(serial::IOException& e)



    {



        ROS_ERROR_STREAM("Unable to open port.");



        return -1;



    }



    



    //判断串口是否打开成功



    if(sp.isOpen())



    {



        ROS_INFO_STREAM("/dev/ttyUSB0 is opened.");



    }



    else



    {



        return -1;



    }

	ros::Subscriber pose_sub=n.subscribe("key_command",10,command_Callback);



    

//

//    if(ros::ok())



//    {



//            uint8_t hello1[12]={0xfa,0x10,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0xfb};

//

//            uint8_t hello2[12]={0xfa,0x10,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0xfb};



//	    uint8_t hello3[12]={0xfa,0x10,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0xfb};



            //把数据发送



//            sp.write(hello1, 12);



//            loop_rate.sleep();



//	    sp.write(hello2, 12);



//            loop_rate.sleep();



//	    sp.write(hello3, 12);



//            loop_rate.sleep();



//    }



    



    //关闭串口



//  sp.close();



    ros::spin(); 



    sp.close();



    return 0;



}

工程代码链接:

catkin_ws_serial.tar-Linux文档类资源-CSDN下载

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Allen953

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值